#include<bits/stdc++.h> using namespace std; #define ll long long inline int read(){ int s=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w; } const int p=998244353,inf=1e9; int n=read(),m=read(); struct node { int fir[6]; int tany[6]; int tone[6][6]; int nany[6][6]; int none[6][6][6]; }f[1<<17]; node merge(node ls,node rs) { node t=ls; for(int i=0; i<6; ++i) if(rs.fir[i]!=inf) for(int j=0; j<6; ++j) t.tone[j][i]=0; memset(t.nany,0,sizeof(t.nany)); memset(t.none,0,sizeof(t.none)); for(int i=0; i<6; ++i) for(int j=0; j<6; ++j) { if(rs.fir[j]==inf) t.nany[i][j]=(t.nany[i][j] +ls.nany[i][j])%p; else { t.tany[i]=(t.tany[i]+1ll*ls.nany[i][j]*rs.tany[j])%p; for(int k=0; k<6; ++k) t.nany[i][k]=(t.nany[i][k]+1ll*ls.nany[i][j]*rs.nany[j][k])%p; } } for(int i=0; i<6; ++i) for(int j=0; j<6; ++j) { int s=0; for(int k=0; k<6; ++k) if(rs.fir[j]==inf&&rs.fir[k]==inf) t.none[i][j][k]=(t.none[i][j][k] +ls.none[i][j][k])%p; else if(rs.fir[j]<=rs.fir[k]) s=(s+ls.none[i][j][k])%p; for(int k=0; k<6; ++k) t.tone[i][k]=(t.tone[i][k]+1ll*s*rs.tone[j][k])%p; for(int k=0; k<6; ++k) for(int l=0; l<6; ++l) t.none[i][k][l]=(t.none[i][k][l] +1ll*s*rs.none[j][k][l])%p; } for(int i=0; i<6; ++i) if(rs.fir[i]!=inf&&ls.fir[i]==inf) { t.fir[i]=rs.fir[i], t.tany[i]=rs.tany[i], // memcpy(t.tany[i],rs.tany[i],sizeof(t.tany[i])); memcpy(t.tone[i],rs.tone[i],sizeof(t.tone[i])); memcpy(t.nany[i],rs.nany[i],sizeof(t.nany[i])); memcpy(t.none[i],rs.none[i],sizeof(t.none[i])); } return t; } char s[50003]; node init(int p) { int v=s[p]-'a'; node z=f[0]; z.fir[v]=p, z.tany[v]=1, z.tone[v][v]=1; for(int i=0; i<6; ++i) z.nany[v][i]=1, z.none[v][i][v]=1; return z; } void build(int nl,int nr,int x) { if(nl==nr){f[x]=init(nl);return ;} int mid=(nl+nr)>>1; build(nl,mid,x<<1),build(mid+1,nr,(x<<1)+1), f[x]=merge(f[x<<1],f[(x<<1)+1]); return ; } void update(int nl,int nr,int t,int x) { if(nl==nr){f[x]=init(nl);return ;} int mid=(nl+nr)>>1; if(t<=mid) update(nl,mid,t,x<<1); else update(mid+1,nr,t,(x<<1)+1); f[x]=merge(f[x<<1],f[(x<<1)+1]); return ; } void solve() { int ans=0; for(int i=0; i<6; ++i) ans=(ans+f[1].tany[i])%p; for(int i=0; i<6; ++i) for(int j=0; j<6; ++j) ans=(ans+p-f[1].tone[i][j])%p; printf("%d\n",ans); } signed main() { for(int i=0; i<6; ++i) f[0].fir[i]=inf; scanf("%s",s+1), build(1,n,1),solve(); for(int x; m--;) x=read(),s[x]=getchar(), update(1,n,x,1),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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | #include<bits/stdc++.h> using namespace std; #define ll long long inline int read(){ int s=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w; } const int p=998244353,inf=1e9; int n=read(),m=read(); struct node { int fir[6]; int tany[6]; int tone[6][6]; int nany[6][6]; int none[6][6][6]; }f[1<<17]; node merge(node ls,node rs) { node t=ls; for(int i=0; i<6; ++i) if(rs.fir[i]!=inf) for(int j=0; j<6; ++j) t.tone[j][i]=0; memset(t.nany,0,sizeof(t.nany)); memset(t.none,0,sizeof(t.none)); for(int i=0; i<6; ++i) for(int j=0; j<6; ++j) { if(rs.fir[j]==inf) t.nany[i][j]=(t.nany[i][j] +ls.nany[i][j])%p; else { t.tany[i]=(t.tany[i]+1ll*ls.nany[i][j]*rs.tany[j])%p; for(int k=0; k<6; ++k) t.nany[i][k]=(t.nany[i][k]+1ll*ls.nany[i][j]*rs.nany[j][k])%p; } } for(int i=0; i<6; ++i) for(int j=0; j<6; ++j) { int s=0; for(int k=0; k<6; ++k) if(rs.fir[j]==inf&&rs.fir[k]==inf) t.none[i][j][k]=(t.none[i][j][k] +ls.none[i][j][k])%p; else if(rs.fir[j]<=rs.fir[k]) s=(s+ls.none[i][j][k])%p; for(int k=0; k<6; ++k) t.tone[i][k]=(t.tone[i][k]+1ll*s*rs.tone[j][k])%p; for(int k=0; k<6; ++k) for(int l=0; l<6; ++l) t.none[i][k][l]=(t.none[i][k][l] +1ll*s*rs.none[j][k][l])%p; } for(int i=0; i<6; ++i) if(rs.fir[i]!=inf&&ls.fir[i]==inf) { t.fir[i]=rs.fir[i], t.tany[i]=rs.tany[i], // memcpy(t.tany[i],rs.tany[i],sizeof(t.tany[i])); memcpy(t.tone[i],rs.tone[i],sizeof(t.tone[i])); memcpy(t.nany[i],rs.nany[i],sizeof(t.nany[i])); memcpy(t.none[i],rs.none[i],sizeof(t.none[i])); } return t; } char s[50003]; node init(int p) { int v=s[p]-'a'; node z=f[0]; z.fir[v]=p, z.tany[v]=1, z.tone[v][v]=1; for(int i=0; i<6; ++i) z.nany[v][i]=1, z.none[v][i][v]=1; return z; } void build(int nl,int nr,int x) { if(nl==nr){f[x]=init(nl);return ;} int mid=(nl+nr)>>1; build(nl,mid,x<<1),build(mid+1,nr,(x<<1)+1), f[x]=merge(f[x<<1],f[(x<<1)+1]); return ; } void update(int nl,int nr,int t,int x) { if(nl==nr){f[x]=init(nl);return ;} int mid=(nl+nr)>>1; if(t<=mid) update(nl,mid,t,x<<1); else update(mid+1,nr,t,(x<<1)+1); f[x]=merge(f[x<<1],f[(x<<1)+1]); return ; } void solve() { int ans=0; for(int i=0; i<6; ++i) ans=(ans+f[1].tany[i])%p; for(int i=0; i<6; ++i) for(int j=0; j<6; ++j) ans=(ans+p-f[1].tone[i][j])%p; printf("%d\n",ans); } signed main() { for(int i=0; i<6; ++i) f[0].fir[i]=inf; scanf("%s",s+1), build(1,n,1),solve(); for(int x; m--;) x=read(),s[x]=getchar(), update(1,n,x,1),solve(); return 0; } |