// Jakub Rozek
// Wielki Zderzacz Termionoow
// PA 2022 A r1
// czas: n + q
// pami: n
#include "bits/stdc++.h"
using namespace std;
const int N=200005;
const long long mod=1000000007;
long long n,q,x,czerwone,zielone,niebieskie,czerwoneparzyste,zieloneparzyste;
string s;
char znak;
long long odwrotnosc3,pierwszyzly;
long long pot2[N];
long long wartosccos[3][6];
long long co3napietrze(int a, int b)
{
long long odp=pot2[a]+mod+wartosccos[b][a%6];
odp%=mod;
odp*=odwrotnosc3;
odp%=mod;
return odp;
}
long long licz()
{
if(n==1)
{
if(s[1]=='N') return 2;
else return 1;
}
long long odp=pot2[niebieskie]+mod-co3napietrze(niebieskie, (pierwszyzly + 3 - czerwone%3)%3 );
odp%=mod;
if(n%2)
{
odp+=mod;
if(czerwoneparzyste==czerwone && zieloneparzyste==0) --odp;
if(czerwoneparzyste==0 && zieloneparzyste==zielone) --odp;
odp%=mod;
}
return odp;
}
void preprocesing()
{
//potegi 2
pot2[0]=1;
for(long long i=1; i<N; ++i)
pot2[i]=(pot2[i-1]*2)%mod;
//co3od0
wartosccos[0][0]=2;
wartosccos[0][1]=1;
wartosccos[0][2]=-1;
wartosccos[0][3]=-2;
wartosccos[0][4]=-1;
wartosccos[0][5]=1;
//co3od1
wartosccos[1][0]=-1;
wartosccos[1][1]=1;
wartosccos[1][2]=2;
wartosccos[1][3]=1;
wartosccos[1][4]=-1;
wartosccos[1][5]=-2;
//co3od2
wartosccos[2][0]=-1;
wartosccos[2][1]=-2;
wartosccos[2][2]=-1;
wartosccos[2][3]=1;
wartosccos[2][4]=2;
wartosccos[2][5]=1;
//odwrotnosc3
odwrotnosc3=333333336;
//pierwszyzly;
if(n%3==0) pierwszyzly=0;
if(n%3==1) pierwszyzly=2;
if(n%3==2) pierwszyzly=1;
}
void ustawznak(int a, int w)
{
if(s[a]=='C') czerwone+=w;
if(s[a]=='Z') zielone+=w;
if(s[a]=='N') niebieskie+=w;
if(a%2==0)
{
if(s[a]=='C') czerwoneparzyste+=w;
if(s[a]=='Z') zieloneparzyste+=w;
}
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin>>n>>q>>s;
s="#"+s;
preprocesing();
for(int i=1; i<=n; ++i) ustawznak(i,1);
cout<<licz()<<"\n";
while(q--)
{
cin>>x>>znak;
ustawznak(x,-1);
s[x]=znak;
ustawznak(x,1);
cout<<licz()<<"\n";
}
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 122 123 124 | // Jakub Rozek // Wielki Zderzacz Termionoow // PA 2022 A r1 // czas: n + q // pami: n #include "bits/stdc++.h" using namespace std; const int N=200005; const long long mod=1000000007; long long n,q,x,czerwone,zielone,niebieskie,czerwoneparzyste,zieloneparzyste; string s; char znak; long long odwrotnosc3,pierwszyzly; long long pot2[N]; long long wartosccos[3][6]; long long co3napietrze(int a, int b) { long long odp=pot2[a]+mod+wartosccos[b][a%6]; odp%=mod; odp*=odwrotnosc3; odp%=mod; return odp; } long long licz() { if(n==1) { if(s[1]=='N') return 2; else return 1; } long long odp=pot2[niebieskie]+mod-co3napietrze(niebieskie, (pierwszyzly + 3 - czerwone%3)%3 ); odp%=mod; if(n%2) { odp+=mod; if(czerwoneparzyste==czerwone && zieloneparzyste==0) --odp; if(czerwoneparzyste==0 && zieloneparzyste==zielone) --odp; odp%=mod; } return odp; } void preprocesing() { //potegi 2 pot2[0]=1; for(long long i=1; i<N; ++i) pot2[i]=(pot2[i-1]*2)%mod; //co3od0 wartosccos[0][0]=2; wartosccos[0][1]=1; wartosccos[0][2]=-1; wartosccos[0][3]=-2; wartosccos[0][4]=-1; wartosccos[0][5]=1; //co3od1 wartosccos[1][0]=-1; wartosccos[1][1]=1; wartosccos[1][2]=2; wartosccos[1][3]=1; wartosccos[1][4]=-1; wartosccos[1][5]=-2; //co3od2 wartosccos[2][0]=-1; wartosccos[2][1]=-2; wartosccos[2][2]=-1; wartosccos[2][3]=1; wartosccos[2][4]=2; wartosccos[2][5]=1; //odwrotnosc3 odwrotnosc3=333333336; //pierwszyzly; if(n%3==0) pierwszyzly=0; if(n%3==1) pierwszyzly=2; if(n%3==2) pierwszyzly=1; } void ustawznak(int a, int w) { if(s[a]=='C') czerwone+=w; if(s[a]=='Z') zielone+=w; if(s[a]=='N') niebieskie+=w; if(a%2==0) { if(s[a]=='C') czerwoneparzyste+=w; if(s[a]=='Z') zieloneparzyste+=w; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin>>n>>q>>s; s="#"+s; preprocesing(); for(int i=1; i<=n; ++i) ustawznak(i,1); cout<<licz()<<"\n"; while(q--) { cin>>x>>znak; ustawznak(x,-1); s[x]=znak; ustawznak(x,1); cout<<licz()<<"\n"; } return 0; } |
English