题解 P4528 【[CTSC2008]图腾】
洛咕 P4528 [CTSC2008]图腾
神题orz。
先约定abcd表示
那么所求就是
1324-1243-1432
=(1x2x-1423)-(14xx-1423)-(12xx-1234)
(其中有x的表示排名任意,但是不能重复)
=1x2x-14xx-12xx+1234
=1x2x-1xxx+13xx+1234
预处理
(可以看出,
分别看怎么求:
1x2x:枚举2的位置
若只考虑
1xxx:很容易,就是
13xx:枚举3,那么4有
只考虑
1234:枚举3,后面的就是
完结撒FA(逃
#include<bits/stdc++.h>
#define il inline
#define vd void
#define mod 16777216
typedef long long ll;
il int gi(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
ll n,p[200010],L[200010],R[200010];
int t[200010];
il vd inc(int&x,int y){x+=y;x%=mod;}
il vd upd(int p,int d){while(p<=n)inc(t[p],d),p+=p&-p;}
il int query(int p){int ret=0;while(p)inc(ret,t[p]),p-=p&-p;return ret;}
int main(){
n=gi();
for(int i=1;i<=n;++i)p[i]=gi();
for(int i=1;i<=n;++i)L[i]=query(p[i]),R[i]=p[i]-1-L[i],upd(p[i],1);
memset(t,0,sizeof t);
int ans=0;
for(int i=1;i<=n;++i){
int x=n-i-R[i];
ans=(ans-(1ll*x*(x-1)*(x-2)/6)%mod+mod)%mod;//1xxx
}
for(int i=1;i<=n;++i)ans=(ans+(n-i-R[i])*query(p[i]))%mod,upd(p[i],L[i]);//1234
memset(t,0,sizeof t);
for(int i=1;i<=n;++i)ans=(ans+(L[i]*(i-1)-query(p[i])-L[i]*(L[i]-1)/2)*(n-i-R[i])%mod+mod)%mod,upd(p[i],i);//1x2x
memset(t,0,sizeof t);
for(int i=n;i;--i)ans=(ans+(query(p[i])-R[i]*(R[i]+1)/2)*(n-i-R[i])%mod+mod)%mod,upd(p[i],p[i]);//13xx
printf("%d\n",ans);
return 0;
}