結果
問題 | No.2294 Union Path Query (Easy) |
ユーザー |
![]() |
提出日時 | 2023-05-05 22:30:16 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 656 ms / 4,000 ms |
コード長 | 4,106 bytes |
コンパイル時間 | 4,521 ms |
コンパイル使用メモリ | 258,776 KB |
最終ジャッジ日時 | 2025-02-12 18:44:47 |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 46 |
ソースコード
#include <stdio.h>#include <bits/stdc++.h>#include <atcoder/all>using namespace atcoder;using mint = modint998244353;using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)#define Inf32 1000000001#define Inf64 4000000000000000001template <class S>struct potentialized_dsu {public:potentialized_dsu() : _n(0) {}potentialized_dsu(int n) : _n(n), parent_or_size(n, -1), d(n) {}int merge(int a, int b, S v) {assert(0 <= a && a < _n);assert(0 <= b && b < _n);int x = leader(a), y = leader(b);if (x == y) return x;if (-parent_or_size[x] < -parent_or_size[y]){std::swap(x, y);std::swap(a, b);S t;v = t - v;}v += diff(x,a);v -= diff(y,b);d[y] += d[x] + v;parent_or_size[x] += parent_or_size[y];parent_or_size[y] = x;return x;}bool same(int a, int b) {assert(0 <= a && a < _n);assert(0 <= b && b < _n);return leader(a) == leader(b);}int leader(int a) {assert(0 <= a && a < _n);if (parent_or_size[a] < 0) return a;int l = leader(parent_or_size[a]);if(parent_or_size[a] != l){d[a] += d[parent_or_size[a]];parent_or_size[a] = l;}return parent_or_size[a];}int size(int a) {assert(0 <= a && a < _n);return -parent_or_size[leader(a)];}S diff(int a,int b){assert(0 <= a && a < _n);assert(0 <= b && b < _n);leader(a);leader(b);return d[b] - d[a];}std::vector<std::vector<int>> groups() {std::vector<int> leader_buf(_n), group_size(_n);for (int i = 0; i < _n; i++) {leader_buf[i] = leader(i);group_size[leader_buf[i]]++;}std::vector<std::vector<int>> result(_n);for (int i = 0; i < _n; i++) {result[i].reserve(group_size[i]);}for (int i = 0; i < _n; i++) {result[leader_buf[i]].push_back(i);}result.erase(std::remove_if(result.begin(), result.end(),[&](const std::vector<int>& v) { return v.empty(); }),result.end());return result;}int _n;// root node: -1 * component size// otherwise: parentstd::vector<int> parent_or_size;std::vector<S> d;};struct xorint{using mytype = xorint;int v = 0;mytype operator+(mytype another)const{return (mytype(*this)+=another);}mytype &operator+=(const mytype &another){(*this).v ^= another.v;return (*this);}mytype operator-(mytype another)const{return (mytype(*this)-=another);}mytype &operator-=(const mytype &another){(*this).v ^= another.v;return (*this);}};int main(){int n,x0,q;cin>>n>>x0>>q;potentialized_dsu<xorint> D(n);vector<int> t(q),a(q),b(q);int x= x0;rep(i,q){cin>>t[i];if(t[i]==1){cin>>a[i]>>b[i];xorint tx;tx.v = b[i];D.merge(a[i],x,tx);}if(t[i]==2){cin>>a[i]>>b[i];if(D.same(a[i],b[i])){x += D.diff(a[i],b[i]).v;x %= n;}}if(t[i]==3){cin>>a[i];}if(t[i]==4){cin>>a[i];x += a[i];x %= n;}}//cout<<'a'<<endl;x = x0;dsu D2(n);vector<array<int,30>> A(n);vector<int> vs(n);rep(i,n){int r = D.diff(i,D.leader(i)).v;vs[i] = r;array<int,30> ta;rep(j,30){ta[j] = (r>>j)&1;}A[i] = ta;}rep(i,q){if(t[i]==1){int la = D2.leader(a[i]),lb = D2.leader(x);if(D2.same(la,lb))continue;D2.merge(la,lb);int lc = D2.leader(la);int ld = lc^la^lb;rep(j,30){A[lc][j] += A[ld][j];A[ld][j] = 0;}}if(t[i]==2){if(D2.same(a[i],b[i])){x += D.diff(a[i],b[i]).v;x %= n;cout<<D.diff(a[i],b[i]).v<<endl;}else{cout<<-1<<endl;}}if(t[i]==3){auto AA = A[D2.leader(a[i])];mint ans =0;rep(j,30){mint ttt = mint(2).pow(j);ttt *= AA[j];ttt *= D2.size(a[i]) - AA[j];ans += ttt;}cout<<ans.val()<<endl;}if(t[i]==4){x += a[i];x %= n;}}return 0;}