CF 2096 H
CF 2096 H
注意到实为计算:
显然我们需要使用 \(FWT\) 进行转化问题,设 \(v(i,j)=(-1)^{|i\cap j|}\)。
不妨设 \(F_i(z)=z^{l_i}+z^{l_i+1}+\dots +z^{r_i}\)
设 \(s(i,j)=\sum_{k=0}^jv(i,k)\)
即,求:
考虑 \(s\) 怎么求。
注意到对于 \(k\) 而言,如二进制位 \(t\) 上是 \(1\),那么对于 \(x\) 与 \(x\oplus 2^t\) 两者的 \(v\) 值相反。
这启发我们:设 \(t\) 为 \(k\) 的 lowbit,则有 \(s(k,2^{t+1}-1)=0\),以至于更多的循环节,也即 \(\forall c\in \mathbb{N},s(k,c2^{t+1}-1)=0\)。
那么就会有:
当确定 \(t\) 时,有 \(s(k,r)=v(\lfloor\frac{k}{2^{t+1}}\rfloor,\lfloor\frac{r}{2^{t+1}}\rfloor)\times s(\lfloor\frac{k}{2^{t+1}}\rfloor,r\bmod 2^{t+1})\)
注意到前面就是 \([z^{\lfloor\frac{k}{2^{t+1}}\rfloor}]FWT(z^{\lfloor\frac{r}{2^{t+1}}\rfloor})\),而后面的可以预处理计算。
不妨设:
当 \(l=0\) 时令 \(b_i=B_i=0\)。让 \(k'=\lfloor\frac{k}{2^{t+1}}\rfloor\)
那么 \(s(k,r)-s(k,l-1)=[z^{k'}](a_iz^{A_i}+b_iz^{B_i})\)
也就是说:
考虑求出后面这个多项式。
不妨再分解一下:
然后,我们将指数上相同的多项式进行合并,合并是容易的:
那么我们就可以将其转化为:设 \(p_i,r_i\) 为合并后的对应 \(z^i\) 这个式的系数。
也就有:
那么 \([z^{k'}]\) 的系数是:
这个东西的计算可以仿照一般的 \(FWT\),维护 \(ad_i=p_i+q_i,de_i=p_i-q_i\),那么在 \(FWT\) 过程中就有:
那么这个题就解决了。
枚举 \(t\),就可以计算一个长度为 \(2^{m-t-1}\) 的多项式,然后将所有 \(lowbit\) 为 \(t\) 的 \(k\) 的答案就算出来了。
最后还原即可。
注意 \(0\) 的值特殊计算。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 1050500
const int p=998244353;
int le[N],ri[N];
struct node{
int ad,de;
}f[N],h[N],tmp[N];
int n,m,a[N],val[N],b[N],c[N],d[N],g[N],na[N],nb[N],bit[N];
void sol(){
cin>>n>>m;g[0]=1;bit[0]=1;
for(int i=1;i<(1<<m);++i)bit[i]=-bit[i^(i&-i)];
for(int i=1;i<=n;++i){
cin>>le[i]>>ri[i];++ri[i];++le[i];
g[0]=g[0]*(ri[i]-le[i]+1)%p;
}
for(int i=0;i<(1<<m);++i){
val[i]=na[i]=nb[i]=0;
}
for(int t=m-1;~t;--t){
for(int i=0;i<(1<<m);++i)val[i]=bit[(1<<t)&i];
for(int i=1;i<(1<<m);++i)val[i]+=val[i-1];
for(int i=0;i<(1<<m);++i)na[i]=1,nb[i]=0;
for(int i=1;i<=n;++i){
a[i]=val[(ri[i]-1)%(1<<t+1)],b[i]=le[i]>1?-val[(le[i]-2)%(1<<t+1)]:0;
c[i]=(ri[i]-1)>>t+1,d[i]=le[i]>1?(le[i]-2>>t+1):0;
int a1=na[c[i]^d[i]],b1=nb[c[i]^d[i]];
na[c[i]^d[i]]=a1*a[i]%p+b1*b[i]%p;
nb[c[i]^d[i]]=a1*b[i]%p+a[i]*b1%p;
a1=na[c[i]],b1=nb[c[i]];
na[c[i]]=0ll*a1+1ll*b1;
nb[c[i]]=a1*1ll+0ll*b1;
}
for(int i=0;i<(1<<m-t-1);++i){
f[i].ad=((na[i]+nb[i])%p+p)%p,f[i].de=((na[i]-nb[i])%p+p)%p,tmp[i]=f[i];
}
for(int len=1;len<(1<<m-t-1);len<<=1)for(int j=0;j<(1<<m-t-1);j+=len<<1)for(int k=0;k<len;++k){
node a=f[j+k],b=f[j+k+len];
f[j+k].ad=a.ad*b.ad%p,f[j+k].de=a.de*b.de%p;
f[j+k+len].ad=a.ad*b.de%p;f[j+k+len].de=a.de*b.ad%p;
}
for(int k=0;k<(1<<m);++k)if((k&-k)==(1<<t))g[k]=f[k>>t+1].ad%p;
}
for(int len=1;len<(1<<m);len<<=1)for(int j=0;j<(1<<m);j+=len<<1)for(int k=0;k<len;++k){
int x=g[j+k],y=g[j+k+len];
g[j+k]=(x+y)%p*(p+1>>1)%p;
g[j+k+len]=(x-y)%p*(p+1>>1)%p;
}int ans=0;
for(int i=0,mul=1;i<(1<<m);++i,mul=mul*2ll%p)g[i]=(g[i]*mul%p+p)%p,ans^=g[i];
cout<<ans<<"\n";
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--)sol();
}

浙公网安备 33010602011771号