#include <bits/stdc++.h> using namespace std; const int MX=270100,md=1000000007; int q,n,nn,i,pos,pw2[MX],b[MX*2][3],cc[2],zz[2]; char s[MX],c[5]; void upd(int& x, int v) { if ((x+=v)>=md) x-=md; } void init(int i, int L, int R) { if (L==R) { b[i][0]=int(s[R-1]!='Z'); b[i][1]=int(s[R-1]!='C'); b[i][2]=0; if (s[R-1]=='N') ++nn; if (s[R-1]=='C') ++cc[R%2]; if (s[R-1]=='Z') ++zz[R%2]; return; } int mid=(L+R)/2; init(i*2,L,mid); init(i*2+1,mid+1,R); for (int j=0; j<3; j++) b[i][j]=0; for (int j=0; j<3; j++) for (int k=0; k<3; k++) upd(b[i][(j+k)%3],(1LL*b[i*2][j]*b[i*2+1][k])%md); } void mdf(int i, int L, int R, int pos, char c) { if (L==R) { b[i][0]=int(c!='Z'); b[i][1]=int(c!='C'); b[i][2]=0; if (s[R-1]=='N') --nn; if (s[R-1]=='C') --cc[R%2]; if (s[R-1]=='Z') --zz[R%2]; s[R-1]=c; if (s[R-1]=='N') ++nn; if (s[R-1]=='C') ++cc[R%2]; if (s[R-1]=='Z') ++zz[R%2]; return; } int mid=(L+R)/2; if (pos<=mid) mdf(i*2,L,mid,pos,c); else mdf(i*2+1,mid+1,R,pos,c); for (int j=0; j<3; j++) b[i][j]=0; for (int j=0; j<3; j++) for (int k=0; k<3; k++) upd(b[i][(j+k)%3],(1LL*b[i*2][j]*b[i*2+1][k])%md); } void solve() { int bad=0; if (n>1) { bad=b[1][(3-n%3)%3]; if (n%2==1) { if (cc[0]==0 && zz[1]==0) upd(bad,1); if (cc[1]==0 && zz[0]==0) upd(bad,1); } } printf("%d\n",(pw2[nn]+md-bad)%md); } int main() { scanf("%d%d",&n,&q); for (pw2[0]=i=1; i<=n; i++) pw2[i]=(pw2[i-1]*2)%md; scanf("%s",s); init(1,1,n); solve(); while (q--) { scanf("%d",&pos); scanf("%s",c); mdf(1,1,n,pos,c[0]); s[pos-1]=c[0]; solve(); } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #include <bits/stdc++.h> using namespace std; const int MX=270100,md=1000000007; int q,n,nn,i,pos,pw2[MX],b[MX*2][3],cc[2],zz[2]; char s[MX],c[5]; void upd(int& x, int v) { if ((x+=v)>=md) x-=md; } void init(int i, int L, int R) { if (L==R) { b[i][0]=int(s[R-1]!='Z'); b[i][1]=int(s[R-1]!='C'); b[i][2]=0; if (s[R-1]=='N') ++nn; if (s[R-1]=='C') ++cc[R%2]; if (s[R-1]=='Z') ++zz[R%2]; return; } int mid=(L+R)/2; init(i*2,L,mid); init(i*2+1,mid+1,R); for (int j=0; j<3; j++) b[i][j]=0; for (int j=0; j<3; j++) for (int k=0; k<3; k++) upd(b[i][(j+k)%3],(1LL*b[i*2][j]*b[i*2+1][k])%md); } void mdf(int i, int L, int R, int pos, char c) { if (L==R) { b[i][0]=int(c!='Z'); b[i][1]=int(c!='C'); b[i][2]=0; if (s[R-1]=='N') --nn; if (s[R-1]=='C') --cc[R%2]; if (s[R-1]=='Z') --zz[R%2]; s[R-1]=c; if (s[R-1]=='N') ++nn; if (s[R-1]=='C') ++cc[R%2]; if (s[R-1]=='Z') ++zz[R%2]; return; } int mid=(L+R)/2; if (pos<=mid) mdf(i*2,L,mid,pos,c); else mdf(i*2+1,mid+1,R,pos,c); for (int j=0; j<3; j++) b[i][j]=0; for (int j=0; j<3; j++) for (int k=0; k<3; k++) upd(b[i][(j+k)%3],(1LL*b[i*2][j]*b[i*2+1][k])%md); } void solve() { int bad=0; if (n>1) { bad=b[1][(3-n%3)%3]; if (n%2==1) { if (cc[0]==0 && zz[1]==0) upd(bad,1); if (cc[1]==0 && zz[0]==0) upd(bad,1); } } printf("%d\n",(pw2[nn]+md-bad)%md); } int main() { scanf("%d%d",&n,&q); for (pw2[0]=i=1; i<=n; i++) pw2[i]=(pw2[i-1]*2)%md; scanf("%s",s); init(1,1,n); solve(); while (q--) { scanf("%d",&pos); scanf("%s",c); mdf(1,1,n,pos,c[0]); s[pos-1]=c[0]; solve(); } return 0; } |