1 条题解
-
0
线段树板子。
#include<bits/stdc++.h> #define int long long #define a3 array<int,3> #define N 300010 #define p 1000000007 #define len(x) (tr[x].r-tr[x].l+1) using namespace std; struct Node{int l,r,tag; a3 dp;}tr[N<<2]; a3 S[N][3]; int n,q,num[N]; inline a3 merge(a3 x,a3 y){ a3 ans; ans[0]=(x[0]*y[0]%p+x[1]*y[2]%p+x[2]*y[1]%p)%p; ans[1]=(x[0]*y[1]%p+x[1]*y[0]%p+x[2]*y[2]%p)%p; ans[2]=(x[0]*y[2]%p+x[2]*y[0]%p+x[1]*y[1]%p)%p; return ans; } void pushdown(int k){ if(tr[k].tag==-1) return; tr[k<<1].tag=tr[k<<1|1].tag=tr[k].tag; tr[k<<1].dp=S[len(k<<1)][tr[k].tag]; tr[k<<1|1].dp=S[len(k<<1|1)][tr[k].tag],tr[k].tag=-1; } void build(int k,int l,int r){ tr[k].l=l,tr[k].r=r,tr[k].tag=-1; if(l==r){tr[k].dp={1,0,0},tr[k].dp[num[l]%3]++;return;} int mid=(l+r)>>1; build(k<<1,l,mid),build(k<<1|1,mid+1,r); tr[k].dp=merge(tr[k<<1].dp,tr[k<<1|1].dp); } void add(int k,int l,int r,int t){ if(l<=tr[k].l&&tr[k].r<=r){tr[k].dp=S[len(k)][t],tr[k].tag=t;return;} pushdown(k); int mid=(tr[k].l+tr[k].r)>>1; if(l<=mid) add(k<<1,l,r,t); if(mid<r) add(k<<1|1,l,r,t); tr[k].dp=merge(tr[k<<1].dp,tr[k<<1|1].dp); } a3 query(int k,int l,int r){ if(l<=tr[k].l&&tr[k].r<=r) return tr[k].dp; pushdown(k); int mid=(tr[k].l+tr[k].r)>>1,u=0; a3 res; if(l<=mid) u=1,res=query(k<<1,l,r); if(mid<r&&u==0) res=query(k<<1|1,l,r); else if(mid<r) res=merge(res,query(k<<1|1,l,r)); return res; } a3 ksm(a3 x,int y){ if(y==1) return x; a3 res=ksm(x,y>>1); res=merge(res,res); return y&1?merge(res,x):res; } signed main(){ cin>>n>>q; char ch; for(int i=1;i<=n;i++) cin>>ch,num[i]=ch-'0'; for(int i=0;i<3;i++){ a3 t={1,0,0}; t[i]++; S[1][i]=t; for(int j=2;j<=n;j++) S[j][i]=merge(S[j-1][i],t); } build(1,1,n); while(q--){ char opt; int x,y,k; cin>>opt>>x>>y>>k; if(opt=='M') add(1,x,y,k%3); else cout<<(ksm(query(1,x,y),k)[0]-1+p)%p<<endl; } }
- 1
信息
- ID
- 312
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 3
- 已通过
- 2
- 上传者