#树状数组#洛谷 4528 bzoj 1145 图腾

题目


分析

d p [ 1324 ] − d p [ 1243 ] − d p [ 1432 ] dp[1324]-dp[1243]-dp[1432] dp[1324]dp[1243]dp[1432] = ( d p [ 1 x 2 x ] − d p [ 1423 ] ) − ( d p [ 12 x x ] − d p [ 1234 ] ) − ( d p [ 14 x x ] − d p [ 1423 ] ) =(dp[1x2x]-dp[1423])-(dp[12xx]-dp[1234])-(dp[14xx]-dp[1423]) =(dp[1x2x]dp[1423])(dp[12xx]dp[1234])(dp[14xx]dp[1423]) = d p [ 1 x 2 x ] − d p [ 12 x x ] + d p [ 1234 ] − d p [ 14 x x ] =dp[1x2x]-dp[12xx]+dp[1234]-dp[14xx] =dp[1x2x]dp[12xx]+dp[1234]dp[14xx] = d p [ 1234 ] + d p [ 1 x 2 x ] + d p [ 13 x x ] − d p [ 1 x x x ] =dp[1234]+dp[1x2x]+dp[13xx]-dp[1xxx] =dp[1234]+dp[1x2x]+dp[13xx]dp[1xxx]
剩下的就是树状数组的事情了,首先可以用树状数组求出位置 i i i左右边比 a i a_i ai小的个数 l [ i ] , r [ i ] l[i],r[i] l[i],r[i]

  • dp[1xxx]:显然为 C r i 3 C_{r_i}^{3} Cri3
  • dp[1234]:枚举2所在的位置 i i i,答案为 ( n − i − r [ i ] ) ∗ ∑ j &lt; i , a [ j ] &lt; a [ i ] l [ j ] (n-i-r[i])*\sum_{j&lt;i,a[j]&lt;a[i]}l[j] (nir[i])j<i,a[j]<a[i]l[j],用树状数组维护
  • dp[1x2x]:枚举2所在的位置 i i i,右边有 n − i − r [ i ] n-i-r[i] nir[i]种情况,左边需满足 k &lt; j &lt; i , a [ k ] &lt; a [ i ] , a [ j ] &gt; a [ i ] k&lt;j&lt;i,a[k]&lt;a[i],a[j]&gt;a[i] k<j<i,a[k]<a[i],a[j]>a[i]
    那么如果只考虑 a [ k ] &lt; a [ i ] a[k]&lt;a[i] a[k]<a[i]显然答案是 l [ i ] ∗ ( i − 1 ) l[i]*(i-1) l[i](i1),那么忽略了 j &lt; k &lt; i 和 k &lt; j &lt; i , a [ j ] &lt; a [ i ] j&lt;k&lt;i和k&lt;j&lt;i,a[j]&lt;a[i] j<k<ik<j<i,a[j]<a[i]的情况,那么分别为 C l [ i ] 2 C_{l[i]}^2 Cl[i]2 ∑ h &lt; i , a [ h ] &lt; a [ i ] j \sum_{h&lt;i,a[h]&lt;a[i]}j h<i,a[h]<a[i]j
    所以答案为 ( n − i − r [ i ] ) ∗ ( l [ i ] ∗ ( i − 1 ) − C l [ i ] 2 − ∑ h &lt; i , a [ h ] &lt; a [ i ] j ) (n-i-r[i])*(l[i]*(i-1)-C_{l[i]}^2-\sum_{h&lt;i,a[h]&lt;a[i]}j) (nir[i])(l[i](i1)Cl[i]2h<i,a[h]<a[i]j)
  • dp[13xx]:枚举3所在的位置 i i i,那么4就有 n − i − r [ i ] n-i-r[i] nir[i]种情况,那么1和2要满足 k &lt; i &lt; j , a [ k ] &lt; a [ j ] &lt; a [ i ] k&lt;i&lt;j,a[k]&lt;a[j]&lt;a[i] k<i<j,a[k]<a[j]<a[i]
    只考虑 a [ k ] &lt; a [ i ] , a [ j ] &lt; a [ i ] , k &lt; i a[k]&lt;a[i],a[j]&lt;a[i],k&lt;i a[k]<a[i],a[j]<a[i],k<i l [ i ] ( a [ i ] − 1 ) l[i](a[i]-1) l[i](a[i]1)种选法,需要减掉的是 i ≥ j i\geq j ij a [ k ] &gt; a [ j ] a[k]&gt;a[j] a[k]>a[j]的情况
    那么也就分别是 C l [ i ] 2 , ∑ h &lt; i , a [ h ] &lt; a [ i ] a [ h ] C_{l[i]}^2,\sum_{h&lt;i,a[h]&lt;a[i]}a[h] Cl[i]2,h<i,a[h]<a[i]a[h]
    所以答案为 ( n − i − r [ i ] ) ∗ ( l [ i ] ∗ ( a [ i ] − 1 ) − C l [ i ] 2 − ∑ h &lt; i , a [ h ] &lt; a [ i ] a [ h ] ) (n-i-r[i])*(l[i]*(a[i]-1)-C_{l[i]}^2-\sum_{h&lt;i,a[h]&lt;a[i]}a[h]) (nir[i])(l[i](a[i]1)Cl[i]2h<i,a[h]<a[i]a[h])

所以真的是一道思维好题呀


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
using namespace std;
const int mod=16777216;
int n,c[200101],l[200101],r[200101],a[200101];
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline signed mo1(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline signed query(int x){rr int ans=0; for (;x;x-=-x&x) ans=mo1(ans,c[x]); return ans;}
inline void update(int x,int y){for (;x<=n;x+=-x&x) c[x]=mo1(c[x],y);}
signed main(){
	n=iut(); rr int ans=0;
	for (rr int i=1;i<=n;++i) a[i]=iut();
	for (rr int i=1;i<=n;++i) l[i]=query(a[i]),r[i]=a[i]-1-l[i],update(a[i],1);
	memset(c,0,sizeof(c));
	for (rr int i=1;i<=n;++i){//1xxx
		rr int x=n-i-r[i];
		ans=mo1(ans,mod-1ll*x*(x-1)*(x-2)/6%mod);
	}
	for (rr int i=1;i<=n;++i) ans=mo1(ans,1ll*(n-i-r[i])*query(a[i])%mod),update(a[i],l[i]);//1234
	memset(c,0,sizeof(c));
	for (rr int i=1;i<=n;++i) ans=mo1(ans,(1ll*l[i]*(i-1)%mod+mod-query(a[i])-1ll*l[i]*(l[i]-1)/2%mod)%mod*(n-i-r[i])%mod),update(a[i],i);//1x2x
    memset(c,0,sizeof(c));
    for (rr int i=n;i;--i) ans=mo1(ans,(query(a[i])+mod-1ll*r[i]*(r[i]+1)/2%mod)%mod*(n-i-r[i])%mod),update(a[i],a[i]);//13xx
    return !printf("%d",mo1(ans,mod));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值