poj 3928——Ping pong
2014-11-19 20:03
246 查看
题意:求一个数组A中有多少个i,j,k,使得Ai<Aj<Ak或者Ai>Aj>Ak
思路:枚举每一个元素,设Ci表示它前面比它小的元素个数,Di表示它后面比它小的元素个数,在第i个位置满足要求的个数就是前面比Ai小的个数乘后面比Ai大的个数,加上前面比Ai大的个数乘后面比Ai小的个数。这样就可以用树状数组来求C和D
错误:树状数组的最后一个应该是Ai取值的最大值,最开始把它当成输入元素的个数导致错误
代码如下:
思路:枚举每一个元素,设Ci表示它前面比它小的元素个数,Di表示它后面比它小的元素个数,在第i个位置满足要求的个数就是前面比Ai小的个数乘后面比Ai大的个数,加上前面比Ai大的个数乘后面比Ai小的个数。这样就可以用树状数组来求C和D
错误:树状数组的最后一个应该是Ai取值的最大值,最开始把它当成输入元素的个数导致错误
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=50005; typedef long long ll; int X[200005]; int A[maxn]; int C[maxn]; int D[maxn]; int n; int lowbit(int a) { return a&-a; } void add(int x,int d){ while(x<=100005){ X[x]+=d;x+=lowbit(x); } } int sum(int x) { int ret=0; while(x>0) { ret+=X[x]; x-=lowbit(x); } return ret; } int main() { //freopen("data.txt","r",stdin); int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%d",&A[i]); } memset(X,0,sizeof(X)); memset(C,0,sizeof(C)); memset(D,0,sizeof(D)); for(int i=1;i<=n;++i) { add(A[i],1); C[i]=sum(A[i])-1; } reverse(A+1,A+n+1); memset(X,0,sizeof(X)); for(int i=1;i<=n;++i) { add(A[i],1); D[n+1-i]=sum(A[i])-1; } ll ans=0; for(int i=1;i<=n;++i) { ans=ans+(ll)C[i]*(n-i-D[i])+(ll)(i-C[i]-1)*D[i]; } cout<<ans<<endl; } return 0; }
相关文章推荐
- POJ 3928 Ping pong(树状数组)
- poj 3928 Ping pong
- POJ 题目3928 Ping pong(树状数组)
- POJ 3928 Ping pong(树状数组)
- poj3928 Ping pong 树状数组
- POJ 3928 Ping pong(树状数组)
- POJ-3928-Ping pong
- poj 3928 Ping pong(数据结构:树状数组)
- POJ 3928-Ping pong(树状数组+加/乘法原理)
- Poj 3928 Ping pong(树状数组)
- poj--3928--ping pong
- POJ 3928 & HDU 2492 Ping pong(树状数组求逆序数)
- POJ 3928 Ping pong (树状数组)
- poj3928 Ping pong 树状数组
- POJ 3928 & HDU 2492 Ping pong(树阵评价倒数)
- POJ 3928 Ping pong(树状数组+两次)
- poj 3928 Ping pong(离散化+树状数组)
- POJ 3928 Ping pong
- POJ 3928 Ping pong【树状数组经典难点实现】PS
- poj 3928 Ping pong 树状数组