CF Round #197 Div.2 D. Xenia and Bit Operations
Codeforces Round #197 Div.2 D. Xenia and Bit Operations
2のn乗個の数列に対して、
奇数番目の数とその次の数同士のorをとって数列をつくる
奇数番目の数とその次の数同士のxorをとって数列をつくる
という操作を数が1個になるまで交互に繰り返す。p番目をbに変えていく、というクエリが与えられるのでそれを順次行なったあとの、最後に残る1個の数をクエリごとに答える問題。セグメントツリーの更新部分を少しいじって実装すればよい。すなわち、2つの子ノードのorまたはxorをとったものを親ノードとして更新する、という操作を繰り返していけば良い。セグメントツリーの問題を解いたのは初めてだったので、「セグメントツリー」でググって見つけたライブラリみたいなものをコピペして、てきとーにごにょごにょ書き換えたら15分ほどであっさり通せた。使いやすい自分なりのライブラリを作りたい。
#include "bits/stdc++.h" using namespace std; #define OUT(x) cout << #x << " = " << x << endl; #define rep(i, n) for (int (i) = 0; (i) < (int)(n); (i)++) #define rer(i, l, r) for (int (i) = (int)(l); (i) <= (int)(r); (i)++) #define reu(i, l, r) for (int (i) = (int)(l); (i) < (int)(r); (i)++) #define each(i, v) for (auto i : v) #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define pb(x) push_back(x) #define bp(x) __builtin_popcount(x) #define mp(x, y) make_pair((x), (y)) #define fi first #define se second #define setp(x) setprecision(x) #define mset(m, v) memset(m, v, sizeof(m)) #define sz(x) (int)(x.size()) static const int INF = 0x3f3f3f3f; static const long long INFL = 0x3f3f3f3f3f3f3f3fLL; static const int MOD = 1000000007; static const double PI = 3.14159265358979; //#define int long long typedef vector<double> vd; typedef vector<string> vs; typedef vector<bool> vb; typedef vector<int> vi; typedef pair<int, int> pii; typedef vector<pii> vpii; template<typename T> void pv(T a, T b) { for (T i = a; i != b; i ++) cout << *i << " "; cout << endl; } template<typename T, typename U> inline void amin(T &x, U y) { if (y < x) x = y; } template<typename T, typename U> inline void amax(T &x, U y) { if (x < y) x = y; } int in() { int _x; scanf("%d", &_x); return _x; } long long lin() {long long _x; scanf("%lld", &_x); return _x; }; #define MAX (2 << 17) struct Segtree { int N, dat[2 * MAX]; Segtree(int n) { N = 1; while (N < n) N *= 2; for (int i = 0; i < 2 * N - 1; i++) dat[i] = INF; } void update(int k, int a) { bool f = true;//最初はorをとる k += N - 1; dat[k] = a; while (k > 0) { k = (k - 1) / 2; if (f) dat[k] = dat[k * 2 + 1] | dat[k * 2 + 2]; else dat[k] = dat[k * 2 + 1] ^ dat[k * 2 + 2]; f ^= 1;//交互に操作する } } }; signed main() { int n, q; cin >> n >> q; Segtree tree(1 << n); rep(i, 1 << n) { int a; cin >> a; tree.update(i, a); } while (q --) { int p, b; cin >> p >> b; tree.update(p - 1, b); cout << tree.dat[0] << endl; } return 0; }
セグメントツリーの問題をこれからじわじわ解いていく。