首页 > 代码库 > poj 3928 Ping pong(树状数组)
poj 3928 Ping pong(树状数组)
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 1352 | Accepted: 509 |
Description
Input
Every test case consists of N + 1 integers. The first integer is N, the number of players. Then N distinct integers a1, a2 ... aN follow, indicating the skill rank of each player, in the order of west to east. (1 <= ai <= 100000, i = 1 ... N).
Output
Sample Input
1 3 1 2 3
Sample Output
1 <span style="font-size:18px;"><strong>首先依照等级值排序 ,那么接下来把研究问题集中到 对下标的研究,依据题目要求能够枚举排序后的每个点找一找位置比它小的 ,和比他大的。 然后两边结果相乘(乘法原理)。结果就是以此点作为裁判时。能够举行的比赛场数。sum(i)-1 为左边小于新插入的数的个数,i-sum(i)-1 为左边大于新插入的元素个数,per【i】.id- 1-(sum(i)-1)为此点右边元素下标小于此点的个数。n-( i-sum(i)-1)-per【i】.id为 右边元素下标大于此点下标的个数。
过程中保证了等级值一定位于每一个元素枚举时的两边。</strong></span> <pre name="code" class="cpp">#include<iostream> #include<sstream> #include<algorithm> #include<cstdio> #include<string.h> #include<cctype> #include<string> #include<cmath> #include<vector> #include<stack> #include<queue> #include<map> #include<set> using namespace std; const int INF=200003; int cnt[INF]; struct A { int v,id; } per[INF]; bool cmp1(A a,A b) { return a.v<b.v; } bool cmp2 ( A a, A b) { return a.v>b.v; } int lowbit(int x) { return x&(-x); } void add(int x,int val) { while(x<INF) { cnt[x]+=val; x+=lowbit(x); } } int sum(int x) { int s=0; while(x>0) { s+=cnt[x]; x-=lowbit(x); } return s; } int main() { int t,n; cin>>t; while(t--) { cin>>n; memset(cnt,0,sizeof(cnt)); long long ans=0; for(int i=1; i<=n; i++) { scanf("%d",&per[i].v); per[i].id=i; } sort(per+1,per+n+1,cmp1); for(int i=1; i<=n; i++) { add(per[i].id,1); long long Lmin=sum(per[i].id)-1; long long Lmax=i-Lmin-1; ans+=( n-Lmax-per[i].id)*Lmin+Lmax*(per[i].id-Lmin-1); } cout<<ans<<endl; } return 0; }
poj 3928 Ping pong(树状数组)