#include<cstdio> #include<iostream> #include<iomanip> #include<algorithm> #include<string> #include<vector> #include<cmath> #include<set> #include<stack> using namespace std; typedef vector<int> VI; typedef long long LL; typedef vector<LL> VLL; typedef pair<int, int> PII; #define FOR(x, b, e) for(int x=b; x<=(e); ++x) #define FORD(x, b, e) for(int x=b; x>=(e); --x) #define REP(x, n) for(int x=0; x<(n); ++x) #define VAR(v, n) __typeof(n) v = (n) #define ALL(c) (c).begin(), (c).end() #define SIZE(x) ((int)(x).size()) #define FOREACH(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i) #define PB push_back #define ST first #define ND second LL p = 1e9 + 7; int n, q; string chain; VLL factorial; LL gcdw(LL a, LL b, LL &l, LL &k) { if(!a) { l = 0; k = 1; return b; } LL d = gcdw(b % a, a, k, l); l -= (b / a) * k; return d; } LL revMod(LL a, LL m) { LL x, y; if(gcdw(a, m, x, y) != 1) return -1; return (x % m + m) % m; } LL newton(int k, int nn) { return factorial[nn] * revMod(factorial[k] * factorial[nn - k] % p, p) % p; } int exclusions(VI &r, VI &g, int b) { if (n == 1) return 0; LL result = 0; int tr = r[0] + r[1]; int tg = g[0] + g[1]; if (n > 3 && n % 3 == 0) { if (tr == 0) result++; if (tg == 0) result++; } if (n % 2 == 0) { if (n / 2 - tr >= 0) result += newton(n / 2 - tr, b); } else { if (r[0] == 0 && g[1] == 0) result++; if (r[1] == 0 && g[0] == 0) result++; int x = (n / 2) - 1; if (x >= tr) result += newton(x - tr, b); if (x >= tg) result += newton(x - tg, b); } return result % p; } int main() { ios_base::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL); cin >> n >> q >> chain; VI ans(n + 1); factorial.resize(n + 1); LL tmp = 1; factorial[0] = 1; for (int i = 1; i <= n; i++) { tmp *= i; tmp %= p; factorial[i] = tmp; } tmp = 1; for (int i = 1; i <= n; i++) { tmp <<= 1; tmp %= p; ans[i] = tmp; } int blue = 0; VI green(2), red(2); REP(i, n) { if (chain[i] == 'C') red[i % 2]++; else if (chain[i] == 'Z') green[i % 2]++; else blue++; } cout << (p + ans[blue] - exclusions(red, green, blue)) % p << '\n'; REP(i, q) { int k; string change; cin >> k >> change; k--; if (chain[k] == 'C') red[k % 2]--; else if (chain[k] == 'Z') green[k % 2]--; else blue--; chain[k] = change[0]; if (chain[k] == 'C') red[k % 2]++; else if (chain[k] == 'Z') green[k % 2]++; else blue++; cout << (p + ans[blue] - exclusions(red, green, blue)) % p << '\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 | #include<cstdio> #include<iostream> #include<iomanip> #include<algorithm> #include<string> #include<vector> #include<cmath> #include<set> #include<stack> using namespace std; typedef vector<int> VI; typedef long long LL; typedef vector<LL> VLL; typedef pair<int, int> PII; #define FOR(x, b, e) for(int x=b; x<=(e); ++x) #define FORD(x, b, e) for(int x=b; x>=(e); --x) #define REP(x, n) for(int x=0; x<(n); ++x) #define VAR(v, n) __typeof(n) v = (n) #define ALL(c) (c).begin(), (c).end() #define SIZE(x) ((int)(x).size()) #define FOREACH(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i) #define PB push_back #define ST first #define ND second LL p = 1e9 + 7; int n, q; string chain; VLL factorial; LL gcdw(LL a, LL b, LL &l, LL &k) { if(!a) { l = 0; k = 1; return b; } LL d = gcdw(b % a, a, k, l); l -= (b / a) * k; return d; } LL revMod(LL a, LL m) { LL x, y; if(gcdw(a, m, x, y) != 1) return -1; return (x % m + m) % m; } LL newton(int k, int nn) { return factorial[nn] * revMod(factorial[k] * factorial[nn - k] % p, p) % p; } int exclusions(VI &r, VI &g, int b) { if (n == 1) return 0; LL result = 0; int tr = r[0] + r[1]; int tg = g[0] + g[1]; if (n > 3 && n % 3 == 0) { if (tr == 0) result++; if (tg == 0) result++; } if (n % 2 == 0) { if (n / 2 - tr >= 0) result += newton(n / 2 - tr, b); } else { if (r[0] == 0 && g[1] == 0) result++; if (r[1] == 0 && g[0] == 0) result++; int x = (n / 2) - 1; if (x >= tr) result += newton(x - tr, b); if (x >= tg) result += newton(x - tg, b); } return result % p; } int main() { ios_base::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL); cin >> n >> q >> chain; VI ans(n + 1); factorial.resize(n + 1); LL tmp = 1; factorial[0] = 1; for (int i = 1; i <= n; i++) { tmp *= i; tmp %= p; factorial[i] = tmp; } tmp = 1; for (int i = 1; i <= n; i++) { tmp <<= 1; tmp %= p; ans[i] = tmp; } int blue = 0; VI green(2), red(2); REP(i, n) { if (chain[i] == 'C') red[i % 2]++; else if (chain[i] == 'Z') green[i % 2]++; else blue++; } cout << (p + ans[blue] - exclusions(red, green, blue)) % p << '\n'; REP(i, q) { int k; string change; cin >> k >> change; k--; if (chain[k] == 'C') red[k % 2]--; else if (chain[k] == 'Z') green[k % 2]--; else blue--; chain[k] = change[0]; if (chain[k] == 'C') red[k % 2]++; else if (chain[k] == 'Z') green[k % 2]++; else blue++; cout << (p + ans[blue] - exclusions(red, green, blue)) % p << '\n'; } return 0; } |