voidsolve() { cin >> n >> a >> b; int sum = 0; bool flag = false; for(int i = 1; i <= n; i++) { int x; cin >> x; sum ^= SG(x); flag |= (a <= x and x <= b); } if(flag or sum != 0) cout << "Alice\n"; else cout << "Bob\n"; }
intSG(int x) { if(x < a) return0; if(a <= x and x <= b) return-1; if(a == 1) return x%(a+b); x = (x-b)%(a+b); if(x/a > 1) return x/a; elsereturn (x/a)^1; }
Visibility Sequence
Description
给一个长度为 N 的数列 H1..N,第 i 项在 [1,Hi] 中选一个数,得到数列 X1..N。
constint N = 3e5+10; typedeflonglong ll; typedef pair<int,int> pir; namespace dsu { ll ans; int fa[N*2], siz[N*2]; int xtot[N*2], ytot[N*2]; vector<pir> opt; voidinit(int n); intfind(int x); boolmerge(int x, int y); boolcheck(int x, int y); voidrollback(); } namespace tr { vector<pir> opt[N*4]; int lim; voidadd(int ql, int qr, pir val, int i = 1, int l = 1, int r = lim); voidsolve(int i = 1, int l = 1, int r = lim); }
int q; ll ans[N]; map<pir, int> mp;
intmain() { cin >> q; tr::lim = q; dsu::init(q); for(int i = 1; i <= q; i++) { pir x; cin >> x.first >> x.second; x.second += q; if(mp.count(x)) { tr::add(mp[x], i-1, x); mp.erase(x); } else mp[x] = i; } for(auto i : mp) tr::add(i.second, q, i.first); tr::solve(); for(int i = 1; i <= q; i++) cout << ans[i] << " "; }
namespace tr { #define ls (i<<1) #define rs (i<<1|1) #define lmid ((l+r)>>1) #define rmid ((l+r+2)>>1) voidadd(int ql, int qr, pir val, int i, int l, int r) { if(ql <= l and r <= qr) return opt[i].push_back(val); if(ql <= lmid) add(ql, qr, val, ls, l, lmid); if(qr >= rmid) add(ql, qr, val, rs, rmid, r); } voidsolve(int i, int l, int r) { int cnt = 0; for(auto x : opt[i]) cnt += dsu::merge(x.first, x.second); if(l == r) ans[l] = dsu::ans; else { solve(ls, l, lmid); solve(rs, rmid, r); } while(cnt--) dsu::rollback(); } }
namespace dsu { voidinit(int n) { for(int i = 1; i <= n*2; i++) { fa[i] = i, siz[i] = 1; xtot[i] = (i <= n); ytot[i] = (i > n); } } intfind(int x) { return fa[x] == x ? x : find(fa[x]); } ll f(int x) { return (ll)xtot[x]*ytot[x]; } boolmerge(int x, int y) { x = find(x), y = find(y); if(x == y) returnfalse; if(siz[x] < siz[y]) swap(x, y); opt.push_back({x, y}); ans -= f(x)+f(y); siz[x] += siz[y]; xtot[x] += xtot[y]; ytot[x] += ytot[y]; fa[y] = x; ans += f(x); returntrue; } boolcheck(int x, int y) { returnfind(x) == find(y); } voidrollback() { int x = opt.back().first; int y = opt.back().second; opt.pop_back(); ans -= f(x); siz[x] -= siz[y]; xtot[x] -= xtot[y]; ytot[x] -= ytot[y]; fa[y] = y; ans += f(x)+f(y); } }