HDU 5792 World is Exploding 2016多校赛第五场 树状数组+容斥原理
2016-08-03 21:00
411 查看
点击打开链接
找出有多少个四元组(a,b,c,d)满足a≠b≠c≠d,a < b,c < d,Aa < Ab,Ac > Ad.
思路:
计算像a,b这样上升的有sm对,像c,d这样下降的有bg对,ans=la*lb。这样是有重复的,重复的就是a与c重合,a与d重合,b与c重合,b与d重合这四种情况。那么减去这四种情况就ok了。可以用树状数组预处理出每一位i的左边比a[i]大的有多少Lb[],小的有多少Ls[],右边比a[i]大的有多少Rb[],小的有多少Ls[]。最后ans减去Rs[i]*Rb[i];
Ls[i]*Lb[i]; Ls[i]*Rs[i]; Lb[i]*Rb[i] 就行了。
如何找sm只需从左到右 树状数组 枚举b点,求前面有多少个比他小的,就是sm // ab
找bg只需从右到左 树状数组 枚举c点,求后面有多少个比他小的,就是bg; //cd
其他的只需要树状数组求即可;
找出有多少个四元组(a,b,c,d)满足a≠b≠c≠d,a < b,c < d,Aa < Ab,Ac > Ad.
思路:
计算像a,b这样上升的有sm对,像c,d这样下降的有bg对,ans=la*lb。这样是有重复的,重复的就是a与c重合,a与d重合,b与c重合,b与d重合这四种情况。那么减去这四种情况就ok了。可以用树状数组预处理出每一位i的左边比a[i]大的有多少Lb[],小的有多少Ls[],右边比a[i]大的有多少Rb[],小的有多少Ls[]。最后ans减去Rs[i]*Rb[i];
Ls[i]*Lb[i]; Ls[i]*Rs[i]; Lb[i]*Rb[i] 就行了。
如何找sm只需从左到右 树状数组 枚举b点,求前面有多少个比他小的,就是sm // ab
找bg只需从右到左 树状数组 枚举c点,求后面有多少个比他小的,就是bg; //cd
其他的只需要树状数组求即可;
#include<bits/stdc++.h> #define LL long long using namespace std; const int N=51000; int tree ; int a ; int b ; int cnt ; int Ls ,Lb ,Rs ,Rb ; int n; int lowbit(int x){ return x&(-x); } int getsum(int x){ int sum=0; while(x>0){ sum+=tree[x]; x-=lowbit(x); } return sum; } void add(int x,int d){ while(x<=n){ tree[x]+=d; x+=lowbit(x); } } int main(){ while(~scanf("%d",&n)){ for(int i=1;i<=n;i++){ scanf("%d",&a[i]); b[i]=a[i]; } sort(b+1,b+n+1); int m=unique(b+1,b+n+1)-b-1; for(int i=1;i<=n;i++){ a[i]=lower_bound(b+1,b+m+1,a[i])-b; } LL sm=0,bg=0; memset(cnt,0,sizeof(cnt));///重复的点个数 memset(tree,0,sizeof(tree)); memset(Lb,0,sizeof(Lb)); memset(Rb,0,sizeof(Rb)); memset(Ls,0,sizeof(Ls)); memset(Rs,0,sizeof(Rs)); for(int i=1;i<=n;i++){ Ls[i]=getsum(a[i]-1); Lb[i]=i-1-Ls[i]-cnt[a[i]]; add(a[i],1); cnt[a[i]]++; sm+=Ls[i]; } memset(cnt,0,sizeof(cnt)); memset(tree,0,sizeof(tree)); for(int i=n;i>=1;i--){ Rs[i]=getsum(a[i]-1); Rb[i]=n-i-Rs[i]-cnt[a[i]]; add(a[i],1); cnt[a[i]]++; bg+=Rs[i]; } LL sum=sm*bg; // cout<<sum<<endl; // for(int i=1;i<=n;i++){ // cout<<Lb[i]<<" "<<Ls[i]<<" "<<Rb[i]<<" "<<Rs[i]<<endl; // } for(int i=1;i<=n;i++){ sum=sum-Ls[i]*Rs[i]; sum=sum-Ls[i]*Lb[i]; sum=sum-Rs[i]*Rb[i]; sum=sum-Lb[i]*Rb[i]; } printf("%lld\n",sum); } return 0; }
相关文章推荐
- (HDU 5792)2016 Multi-University Training Contest 5 World is Exploding (逆序数、顺序数、树状数组)
- hdu 5792 World is Exploding 2016 Multi-University 5
- hdu 5792 World is Exploding(2016 Multi-University Training Contest 5——树状数组)
- HDU 5792 World is Exploding(BIT)
- HDU5792(2016多校第五场)——World is Exploding(树状数组,离散化)
- HDU_5792_WorldIsExploding(树状数组&&离散化)
- HDU 5792 World is Exploding
- HDU 5792 World is Exploding 树状数组+枚举
- HDU-5792-World is Exploding(树状数组+离散化)
- hdu 5792 World is Exploding 离散化+树状数组
- HDU 5792 World is Exploding
- HDOJ 5792 (2016多校联合训练 Training Contest 5) World is Exploding
- (HDU 5792)World is Exploding <树状数组+去重> 多校训练5
- HDU 5792 World is Exploding (树状数组逆序对)
- hdu_5792_World is Exploding(树状数组+逆序对)
- HDU 5792 World is Exploding (容斥原理+离散化+树状数组)
- HDU-5792 World is Exploding(树状数组)
- hdu 5792 World is Exploding 树状数组
- HDU 5792 World is Exploding (树状数组)
- HDU 5792 - World is Exploding