#include<bits/stdc++.h> using namespace std; typedef long long ll; int read() { int x;scanf("%d",&x);return x; } ll mod=998244353ll,ans; ll inv[100010],fac[100010]; ll quick(ll a,ll b) { ll t=1; while(b) { if(b&1) t=t*a%mod; a=a*a%mod; b=b/2; } return t; } ll C(ll n,ll m) { return fac[m]*inv[n]%mod*inv[m-n]%mod; } int c[100010*4][4][4],lazy[400010],xx,yy; int a[100010],t[4][4],tl[4][4],tr[4][4],lp[400010],rp[400010]; char s[100010]; void build(int x,int l,int r) { if(l==r){ lp[x]=rp[x]=a[l]; return ; } int mid=(l+r)/2; build(x*2,l,mid); build(x*2+1,mid+1,r); for(int i=0;i<4;i++) for(int j=0;j<4;j++) c[x][i][j]=c[x*2][i][j]+c[x*2+1][i][j]; c[x][a[mid]][a[mid+1]]++; lp[x]=lp[x*2]; rp[x]=rp[x*2+1]; } void pushdown(int x,int l,int r) { if(lazy[x]==0) return ; lazy[l]=(lazy[l]+lazy[x])%4; lazy[r]=(lazy[r]+lazy[x])%4; lp[l]=(lp[l]+lazy[x])%4; rp[l]=(rp[l]+lazy[x])%4; lp[r]=(lp[r]+lazy[x])%4; rp[r]=(rp[r]+lazy[x])%4; for(int i=0;i<4;i++) for(int j=0;j<4;j++) { tl[i][j]=c[l][i][j]; tr[i][j]=c[r][i][j]; } for(int i=0;i<4;i++) for(int j=0;j<4;j++) { c[l][(i+lazy[x])%4][(j+lazy[x])%4]=tl[i][j]; c[r][(i+lazy[x])%4][(j+lazy[x])%4]=tr[i][j]; } } void add(int x,int l,int r,int tl,int tr) { if(tl<=l&&r<=tr) { lazy[x]=(lazy[x]+1)%4; if(l==r) { rp[x]=lp[x]=(lp[x]+1)%4; } else { lp[x]=(lp[x]+1)%4; rp[x]=(rp[x]+1)%4; } for(int i=0;i<4;i++) for(int j=0;j<4;j++) t[i][j]=c[x][i][j]; for(int i=0;i<4;i++) for(int j=0;j<4;j++) c[x][(i+1)%4][(j+1)%4]=t[i][j]; return ; } if(lazy[x]) pushdown(x,x*2,x*2+1); int mid=(l+r)/2; if(tr<=mid) add(x*2,l,mid,tl,tr); else if(tl>mid) add(x*2+1,mid+1,r,tl,tr); else { add(x*2,l,mid,tl,tr); add(x*2+1,mid+1,r,tl,tr); } for(int i=0;i<4;i++) for(int j=0;j<4;j++) c[x][i][j]=c[x*2][i][j]+c[x*2+1][i][j]; c[x][rp[x*2]][lp[x*2+1]]++; lp[x]=lp[x*2]; rp[x]=rp[x*2+1]; } void ask(int x,int l,int r,int tl,int tr) { if(tl<=l&&r<=tr) { for(int i=0;i<4;i++) for(int j=0;j<4;j++) t[i][j]+=c[x][i][j]; return ; } if(lazy[x])pushdown(x,x*2,x*2+1); int mid=(l+r)/2; if(tr<=mid) ask(x*2,l,mid,tl,tr); else if(tl>mid) ask(x*2+1,mid+1,r,tl,tr); else { ask(x*2,l,mid,tl,tr); ask(x*2+1,mid+1,r,tl,tr); t[rp[x*2]][lp[x*2+1]]++; } } int main() { // freopen("1.in","r",stdin); fac[0]=1; for(int i=1;i<=100000;i++) fac[i]=fac[i-1]*i%mod; inv[100000]=quick(fac[100000],mod-2); for(int i=99999;~i;i--) inv[i]=inv[i+1]*(i+1)%mod; int n=read();int q=read(); scanf("%s",s+1); for(int i=1;i<=n;i++) a[i]=s[i]-'A'; build(1,1,n); int l,r,k; for(int i=1;i<=q;i++) { if(read()&1) { l=read();r=read(); add(1,1,n,l,r); } else { l=read();r=read();k=read(); if(l==r) { printf("1\n"); continue; } for(int ii=0;ii<4;ii++) for(int j=0;j<4;j++) t[ii][j]=0; ask(1,1,n,l,r);//Áît±ä³ÉÇø¼äÀïÊýÁ¿ int fuyi=1; for(int ii=0;ii<4;ii++) for(int j=0;j<=ii;j++) fuyi+=t[ii][j]; if(fuyi>k) printf("%lld\n",0ll); else printf("%lld\n",C(k-fuyi,r-l+1-fuyi)); } } // cout<<ans; }
标签:int,存档,ll,tr,mid,tl,100010,省赛,线段 From: https://www.cnblogs.com/qywyt/p/16749469.html