jzoj6342-[NOIP2019模拟2019.9.7]Tiny Counting【树状数组,容斥】
正題
題目大意
一個序列SSS,求有多少個互不相同的4元組(a,b,c,d)(a,b,c,d)(a,b,c,d)使得a<b且Sa<Sba<b且S_a<S_ba<b且Sa?<Sb?
c<b且Sc>Sdc<b且S_c>S_dc<b且Sc?>Sd?
解題思路
若可以重復其實答案就是逆序對個數乘上正序對個數。
然后我們考慮將重復的去掉
這里定義up1,down1up_1,down_1up1?,down1?為左邊大于/小于該數的個數,up2,down2up2,down2up2,down2為右邊大于/小于該數的個數。
若a=ca=ca=c,那么有Sd<Sa=c<SbS_d<S_{a=c}<S_bSd?<Sa=c?<Sb?,且(a=c)<b,d(a=c)< b,d(a=c)<b,d,為up2?down2up2*down2up2?down2
若a=da=da=d,那么有Sc>Sa=d<SbS_c>S_{a=d}<S_bSc?>Sa=d?<Sb?,且c<(a=d)<bc<(a=d)<bc<(a=d)<b,為up1?up2up1*up2up1?up2
若b=cb=cb=c,那么有Sa<Sb=c>SdS_a<S_{b=c}>S_dSa?<Sb=c?>Sd?,且a<(b=d)<da<(b=d)<da<(b=d)<d,為down1?down2down1*down2down1?down2
若b=db=db=d,那么有Sa<Sb=d<ScS_a<S_{b=d}<S_cSa?<Sb=d?<Sc?,且a,c<(b=d)a,c<(b=d)a,c<(b=d),為up1?down1up1*down1up1?down1
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #define lowbit(x) (x&-x) #define ll long long using namespace std; const ll N=1e5+100; ll n,a[N],c[N],s1,s2,z,m; struct Tree_array{ll t[N];void Clear(){memset(t,0,sizeof(t));}void Change(ll x,ll z){while(x<=m){t[x]+=z;x+=lowbit(x);}}ll Ask(ll x){ll ans=0;while(x){ans+=t[x];x-=lowbit(x);} return ans;} }T1,T2; int main() {freopen("a.in","r",stdin);freopen("a.out","w",stdout);scanf("%lld",&n);for(ll i=1;i<=n;i++)scanf("%lld",&a[i]),c[i]=a[i];sort(c+1,c+1+n);m=unique(c+1,c+1+n)-c-1;for(ll i=1;i<=n;i++){a[i]=lower_bound(c+1,c+1+m,a[i])-c;T2.Change(a[i],1);}for(ll i=1;i<=n;i++){ll down1=T1.Ask(a[i]-1),up1=T1.Ask(m)-T1.Ask(a[i]);ll down2=T2.Ask(a[i]-1),up2=T2.Ask(m)-T2.Ask(a[i]);s1+=down1;s2+=down2;z+=up2*down2+up1*up2+down1*down2+up1*down1;T1.Change(a[i],1);T2.Change(a[i],-1);}printf("%lld",s1*s2-z); }總結
以上是生活随笔為你收集整理的jzoj6342-[NOIP2019模拟2019.9.7]Tiny Counting【树状数组,容斥】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 牛客练习赛51-记录
- 下一篇: 蓝牙 Mesh 网关好选择:小米小爱音箱