欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

jzoj6342-[NOIP2019模拟2019.9.7]Tiny Counting【树状数组,容斥】

发布时间:2023/12/3 56 豆豆
生活随笔 收集整理的这篇文章主要介绍了 jzoj6342-[NOIP2019模拟2019.9.7]Tiny Counting【树状数组,容斥】 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

正题


题目大意

一个序列SSS,求有多少个互不相同的4元组(a,b,c,d)(a,b,c,d)(a,b,c,d)使得a&lt;b且Sa&lt;Sba&lt;b且S_a&lt;S_ba<bSa<Sb
c&lt;b且Sc&gt;Sdc&lt;b且S_c&gt;S_dc<bSc>Sd


解题思路

若可以重复其实答案就是逆序对个数乘上正序对个数。

然后我们考虑将重复的去掉
这里定义up1,down1up_1,down_1up1,down1为左边大于/小于该数的个数,up2,down2up2,down2up2,down2为右边大于/小于该数的个数。
a=ca=ca=c,那么有Sd&lt;Sa=c&lt;SbS_d&lt;S_{a=c}&lt;S_bSd<Sa=c<Sb,且(a=c)&lt;b,d(a=c)&lt; b,d(a=c)<b,d,为up2∗down2up2*down2up2down2
a=da=da=d,那么有Sc&gt;Sa=d&lt;SbS_c&gt;S_{a=d}&lt;S_bSc>Sa=d<Sb,且c&lt;(a=d)&lt;bc&lt;(a=d)&lt;bc<(a=d)<b,为up1∗up2up1*up2up1up2
b=cb=cb=c,那么有Sa&lt;Sb=c&gt;SdS_a&lt;S_{b=c}&gt;S_dSa<Sb=c>Sd,且a&lt;(b=d)&lt;da&lt;(b=d)&lt;da<(b=d)<d,为down1∗down2down1*down2down1down2
b=db=db=d,那么有Sa&lt;Sb=d&lt;ScS_a&lt;S_{b=d}&lt;S_cSa<Sb=d<Sc,且a,c&lt;(b=d)a,c&lt;(b=d)a,c<(b=d),为up1∗down1up1*down1up1down1


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【树状数组,容斥】的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。