#include<bits/stdc++.h> usingnamespace std; using ll = longlong; using uint = unsigned; using ull = unsignedlonglong;
intmain(){ int J; cin >> J;
while (J--) { ull x = 0, y = 0;
ull a = 0; for (int bit = 0; bit < 30; bit += 2) { a |= 1ull << bit; } cout << a << endl; cin >> a;
for (int bit = 1; bit < 30; bit += 2) { ull tmp = a >> bit & 3; assert(tmp); if (tmp == 2) { x |= 1ull << bit; } elseif (tmp == 3) { x |= 1ull << bit; y |= 1ull << bit; } }
ull b = 0; for (int bit = 1; bit < 30; bit += 2) { b |= 1ull << bit; } cout << b << endl; cin >> b; b++; for (int bit = 0; bit < 30; bit += 2) { ull tmp = b >> bit & 3; assert(tmp); if (tmp == 2) { x |= 1ull << bit; } elseif (tmp == 3) { x |= 1ull << bit; y |= 1ull << bit; } }
cout << "!" << endl; cin >> a; cout << (a | x) + (a | y) << endl; }
Z cnt = 1; Z sum = s[0] == '1' ? 1 : -1; Z res = 0; for (int i = 1; i < n; i++) { if (s[i] == '1') { res *= 2; res += (sum + cnt) / 2; cnt *= 2; sum *= 2; sum += cnt; } else { res *= 2; res -= (sum - cnt) / 2; cnt *= 2; sum *= 2; sum -= cnt; } }
Hint 3 为修改,上述过程可逆吗?
Hint 2 中把三个变量作修改,重新赋值,这过程可以看作一个方程组。显然这个方程组可逆。通过新值解出旧值,也就 撤销 了增加一个数这个操作。
usingnamespace std; using ll = longlong; using uint = unsigned; using ull = unsignedlonglong; using ulll = unsigned __int128;
constexpr ll mod = 998244353;
template<class T> constexpr T qpow(T a, ull b, T res = 1){ for (; b != 0; b /= 2, a *= a) if (b & 1) res *= a; return res; } template<uint M> constexpr uint mul(uint a, uint b){ returnull(a) * b % M; } template<ull M> constexpr ull mul(ull a, ull b){ return (a * b - ull(1.L * a * b / M - 0.5L) * M) % M; }
template<unsigned_integral U, U M> structmull { constexprmull() : x(0) {} template<unsigned_integral T> constexprmull(T x) : x(x % mod()) {} template<signed_integral T> constexprmull(T x){ make_signed_t<U> v = x % make_signed_t<U>(mod()); if (v < 0) v += mod(); this->x = v; } constexprstatic U mod(){ return M; } constexpr U val()const{ return x; } constexpr mull operator-() const { mull res; res.x = (x == 0 ? 0 : mod() - x); return res; } constexpr mull& operator*=(const mull& b) & { x = mul<mod()>(x, b.val()); return *this; } constexpr mull& operator+=(const mull& b) & { x += b.val(); if (x >= mod()) x -= mod(); return *this; } constexpr mull& operator-=(const mull& b) & { x -= b.val(); if (x >= mod()) x += mod(); return *this; } constexpr mull& operator/=(const mull& b) & { return *this *= qpow(b, mod() - 2); } friendconstexpr mull operator*(mull a, const mull& b) { return a *= b; } friendconstexpr mull operator+(mull a, const mull& b) { return a += b; } friendconstexpr mull operator-(mull a, const mull& b) { return a -= b; } friendconstexpr mull operator/(mull a, const mull& b) { return a /= b; } friendconstexpr istream& operator>>(istream& is, mull& a) { ll i; is >> i; a = i; return is; } friendconstexpr ostream& operator<<(ostream& os, const mull& a) { return os << a.val(); } friendconstexprbooloperator==(const mull& a, const mull& b) { return a.val() == b.val(); } friendconstexpr strong_ordering operator<=>(const mull& a, const mull& b) { return a.val() <=> b.val(); } private: U x; }; using Z = mull<ull, mod>;
while (J--) { int n, q; cin >> n >> q; string s; cin >> s;
Z cnt = 1; Z sum = s[0] == '1' ? 1 : -1; Z res = 0; for (int i = 1; i < n; i++) { if (s[i] == '1') { res *= 2; res += (sum + cnt) / 2; cnt *= 2; sum *= 2; sum += cnt; } else { res *= 2; res -= (sum - cnt) / 2; cnt *= 2; sum *= 2; sum -= cnt; } }
while (q--) { int i; cin >> i; i--; if (s[i] == '1') { sum -= cnt; res -= sum / 2; sum -= cnt; s[i] = '0'; } else { sum += cnt; res += sum / 2; sum += cnt; s[i] = '1'; } cout << res << endl; } }