b_hdu_Ping pong(樹狀陣列+乘法原理)
阿新 • • 發佈:2020-11-04
有n個人要進行乒乓球比賽每一個人都一個能力值;現在要求進行一場1個裁判2個選手的比賽,不能選擇技術等級高於或低於他們兩人的裁判,裁判位置也需在兩人的中間,問一共可以進行這種比賽多少次。(1<=ai<=100000, N<20000)
1
3 1 2 3
1
思路
樹狀陣列+乘法原理
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+5; ll n, ans, a[N], c[N], lmin[N], rmax[N], lmax[N], rmin[N]; int lowbit(int x) {return x&-x;} void add(int x, ll v) { for (; x<N; x+=lowbit(x)) c[x]+=v; } ll ask(int x) { ll ans=0; for (; x>0; x-=lowbit(x)) ans+=c[x]; return ans; } int main() { std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t; cin>>t; while (t--) { memset(c,0,sizeof c); cin>>n; for (int i=1; i<=n; i++) cin>>a[i], lmin[i]=lmax[i]=rmin[i]=rmax[i]=0; for (int i=1; i<=n; i++) { ll l=ask(a[i]); lmin[i]=l, lmax[i]=i-l-1; add(a[i], 1); } memset(c,0,sizeof c); for (int i=n,j=1; i>0; i--,j++) { ll r=ask(a[i]); //右邊比a[i].v小的數的個數 rmin[i]=r, rmax[i]=j-r-1; add(a[i], 1); } // for (int i=1; i<=n; i++) cout<<lmin[i]; // cout<<'\n'; // for (int i=1; i<=n; i++) cout<<lmax[i]; // cout<<'\n'; // for (int i=1; i<=n; i++) cout<<rmin[i]; // cout<<'\n'; // for (int i=1; i<=n; i++) cout<<rmax[i]; for (int i=1; i<=n; i++) ans+=lmin[i]*rmax[i]+lmax[i]*rmin[i]; cout<<ans<<'\n'; } return 0; }