码风可能有些丑,望谅解。
#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T& t){
t=0;register char ch=getchar();register int fflag=1;
while(!('0'<=ch&&ch<='9')){if(ch=='-')fflag=-1;ch=getchar();}
while('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}t*=fflag;
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t);read(args...);}
const int MOD=19940417,N=5e4+5;
typedef long long ll;
int n,m,a[N],com[N][21];
#define ls p<<1
#define rs p<<1|1
#define add_mod(x) x>=MOD?x-MOD:x
struct NODE{
ll sig[21];
int l,r,add,mul;
inline void addupd(int k){
register ll tk;
for(int i=min(r-l+1,20);i>=1;--i){
tk=k;
for(int j=1;j<=i;++j,tk=tk*k%MOD){
sig[i]+=sig[i-j]*com[r-l+1-i+j][j]%MOD*tk%MOD;
}
sig[i]%=MOD;
// assert(sig[i]>=0);
}
}
inline void mulupd(){
for(int i=1;i<=min(r-l+1,20);i+=2){
sig[i]=MOD-sig[i];
// assert(sig[i]>=0);
}
}
NODE(){
memset(sig,0,sizeof(sig));
add=mul=l=r=0;
}
void print(int k){
printf("%d~%d:",l,r);
for(int i=0;i<=k;++i)printf("%lld%c",sig[i],i==k?'\n':' ');
}
}ans;
struct Segment_Tree{
NODE nod[N<<2];
void push_up(int p,int l,int r){
int mid=l+r>>1;
for(int i=1;i<=min(r-l+1,20);++i){
nod[p].sig[i]=0;
for(int j=0;j<=min(r-mid,i);++j)
nod[p].sig[i]+=nod[rs].sig[j]*nod[ls].sig[i-j];
nod[p].sig[i]%=MOD;
// assert(nod[p].sig[i]>=0);
}
// nod[p].print(n);
}
void push_down(int p,int l,int r){
int mid=l+r>>1;
if(nod[p].mul){
nod[ls].mul^=1,nod[rs].mul^=1;
nod[ls].add=MOD-nod[ls].add,nod[rs].add=MOD-nod[rs].add;
nod[ls].mulupd();nod[rs].mulupd();
nod[p].mul=0;
}
if(nod[p].add){
nod[ls].add=add_mod(nod[ls].add+nod[p].add),
nod[rs].add=add_mod(nod[rs].add+nod[p].add);
nod[ls].addupd(nod[p].add);nod[rs].addupd(nod[p].add);
nod[p].add=0;
}
}
inline void build(int p,int l,int r){
nod[p].sig[0]=1;nod[p].l=l,nod[p].r=r;nod[p].add=nod[p].mul=0;
if(l==r)return void(nod[p].sig[1]=a[l]%MOD);
int mid=l+r>>1;
build(ls,l,mid),build(rs,mid+1,r);
push_up(p,l,r);
}
inline void modifyI(int al,int ar,int p,int l,int r,int k){
if(al<=l&&r<=ar){
nod[p].add=add_mod(nod[p].add+(k<0?MOD-k:k));
// nod[p].print(n);
nod[p].addupd(k<0?MOD-k:k);
// nod[p].print(n);
return ;
}
push_down(p,l,r);
int mid=l+r>>1;
if(al<=mid)modifyI(al,ar,ls,l,mid,k);
if(mid<ar)modifyI(al,ar,rs,mid+1,r,k);
push_up(p,l,r);
}
inline void modifyR(int al,int ar,int p,int l,int r){
if(al<=l&&r<=ar){
nod[p].mul^=1;
if(nod[p].add)nod[p].add=MOD-nod[p].add;
nod[p].mulupd();
// nod[p].print(n);
return ;
}
push_down(p,l,r);
int mid=l+r>>1;
if(al<=mid)modifyR(al,ar,ls,l,mid);
if(mid<ar)modifyR(al,ar,rs,mid+1,r);
push_up(p,l,r);
}
inline NODE query(int al,int ar,int p,int l,int r,int k){
if(al<=l&&r<=ar){
// nod[p].print(k);
return nod[p];
}
push_down(p,l,r);
int mid=l+r>>1,flag=0;
NODE tmp1,tmp2;
if(al<=mid)tmp1=query(al,ar,ls,l,mid,k),flag=1;
if(mid<ar){
NODE res;
if(flag){
tmp2=query(al,ar,rs,mid+1,r,k);
register int ll=tmp1.l,rr=tmp2.r;
for(int i=0;i<=k&&i<=mid-ll+1;++i)
for(int j=0;j<=k&&i+j<=k&&j<=rr-mid;++j)
res.sig[i+j]+=tmp1.sig[i]*tmp2.sig[j];
for(int i=0;i<=k&&i<=rr-ll+1;++i)res.sig[i]%=MOD;//assert(res.sig[i]>=0);
res.l=ll,res.r=rr;
}
else res=query(al,ar,rs,mid+1,r,k);
// res.print(k);
return res;
}
// tmp1.print(k);
return tmp1;
}
}tr;
int main(){
read(n,m);
com[0][0]=1;
for(int i=1;i<=n;++i){
com[i][0]=1;
for(int j=1;j<=20;++j)
com[i][j]=add_mod(com[i-1][j-1]+com[i-1][j]);
}
for(int i=1;i<=n;++i)read(a[i]),a[i]=(a[i]%MOD+MOD)%MOD;
tr.build(1,1,n);
while(m--){
char opt;
scanf("%c",&opt);
int a,b,c;
switch(opt){
case 'I':{
read(a,b,c);
c%=MOD;
tr.modifyI(a,b,1,1,n,add_mod(MOD+c));
break;
}
case 'R':{
read(a,b);
tr.modifyR(a,b,1,1,n);
break;
}
case 'Q':{
read(a,b,c);
ans=tr.query(a,b,1,1,n,c);
printf("%lld\n",(ans.sig[c]%MOD+MOD)%MOD);
break;
}
}
}
return 0;
}
希望大佬能指出错误,如果可以希望能提供小一些的hack数据。个人怀疑我取模有问题