[ABC221E]LEQ(数学+树状数组)

给定整数数列 \(A=(A_1,A_2,...,A_n)\),计算其合法子序列个数。满足如下条件的子序列 \(A'=(A'_1,A'_2,...,A'_k)\) 合法:

  • \(k\ge 2\)
  • \(A'_1\le A'_k\)

答案对 \(998244353\) 取模。\(2\le N\le 3\times 10^5,1\le A_i\le 10^9\)

发现对于每一个顺序对 \((i,j)\),它的贡献是 \(2^{j-i-1}\)——中间的数可选可不选。自然想到枚举 \(i,j\),复杂度 \(O(n^2)\)。考虑怎样优化:将式子转化,\(2^{j-i-1}=\frac{2^{j-1}}{2^i}\),我们可以枚举 \(j\)\(2^{j-1}\) 用快速幂计算,而 \({2^i}\) 用树状数组维护(坐标需要离散化)。除法不能取模,维护模数逆元即可。

下面是 AC 代码片段:

const int mod=98244353;
//main()
const ll div=_pow(2,mod-2);
ll ans=0;
for(int i=1;i<=n;++i)
{
	ans=(ans+_pow(2,i-1)*ask(a[i])%mod)%mod;
	add(a[i],_pow(div,i));
}
printf("%lld\n",ans);

THE END

posted @ 2021-10-19 14:40  q0000000  阅读(163)  评论(0编辑  收藏  举报