結果
| 問題 |
No.2295 Union Path Query (Medium)
|
| コンテスト | |
| ユーザー |
沙耶花
|
| 提出日時 | 2023-05-05 22:49:47 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,281 bytes |
| コンパイル時間 | 4,016 ms |
| コンパイル使用メモリ | 263,224 KB |
| 最終ジャッジ日時 | 2025-02-12 19:11:47 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 50 TLE * 3 |
ソースコード
#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 4000000000000000001
template <typename T>
struct perArray{
struct node{
T value;
int l=-1,r=-1;
};
int sz;
vector<node> nodes;
vector<int> roots;
void build(vector<T> v,int now = -1){
if(now==-1){
sz = v.size();
nodes.push_back(node());
now = 0;
roots.push_back(0);
}
if(v.size()==1){
nodes[now].value = v[0];
return;
}
vector<T> l,r;
rep(i,v.size()){
if(i<v.size()/2){
l.push_back(v[i]);
}
else{
r.push_back(v[i]);
}
}
nodes[now].l = nodes.size();
nodes.push_back(node());
build(l,nodes[now].l);
nodes[now].r = nodes.size();
nodes.push_back(node());
build(r,nodes[now].r);
}
int set(int p, int ind, T x, int now = -1, int length = -1){
int ret = roots.size();
if(now==-1){
roots.push_back(nodes.size());
now = nodes.size();
nodes.push_back(nodes[roots[p]]);
length = sz;
}
if(length==1){
nodes[now].value = x;
}
else{
if(ind < (length>>1)){
int temp = nodes[now].l;
nodes[now].l = nodes.size();
nodes.push_back(nodes[temp]);
set(p,ind,x,nodes.size()-1,(length>>1));
}
else{
int temp = nodes[now].r;
nodes[now].r = nodes.size();
nodes.push_back(nodes[temp]);
set(p,ind - (length>>1),x,nodes.size()-1,(length+1)>>1);
}
}
return ret;
}
T get(int p,int ind,int now = -1,int length = -1){
if(now==-1){
now = roots[p];
length = sz;
}
if(length==1)return nodes[now].value;
if(ind<(length>>1)){
return get(p,ind,nodes[now].l,length>>1);
}
else{
return get(p,ind - (length>>1),nodes[now].r,(length+1)>>1);
}
}
int size(){
return sz;
}
};
struct perDsu{
perArray<int> A;
vector<int> roots;
perDsu(int n){
vector<int> t(n,-1);
A.build(t);
roots.push_back(0);
}
int merge(int p,int a,int b){
int ret = roots.size();
int La = leader(p,a);
int Lb = leader(p,b);
if(La==Lb)return p;
if(size(p,La)<size(p,Lb))swap(La,Lb);
int temp = A.set(roots[p],La,-(size(p,La)+size(p,Lb)));
roots.push_back(A.set(temp,Lb,La));
return ret;
}
bool same(int p,int a,int b){
return (leader(p,a)==leader(p,b));
}
int size(int p,int a){
int temp = A.get(roots[p],a);
if(temp<0)return -temp;
return size(p,temp);
}
int leader(int p,int a){
int temp = A.get(roots[p],a);
if(temp<0)return a;
return leader(p,temp);
}
vector<vector<int>> groups(int p){
vector<vector<int>> temp(A.size(),vector<int>());
rep(i,A.size()){
temp[leader(p,i)].push_back(i);
}
vector<vector<int>> ret;
rep(i,temp.size()){
if(temp[i].size()>0)ret.push_back(temp[i]);
}
return ret;
}
};
int main(){
int n,x0,q;
cin>>n>>x0>>q;
perDsu D(n);
vector<int> t(q+1),a(q+1),b(q+1),p(q+1);
int x= x0;
for(int i=1;i<=q;i++){
cin>>t[i];
p[i] = p[i-1];
if(t[i]==1){
cin>>a[i]>>b[i];
p[i] = D.merge(p[i],a[i],x);
}
if(t[i]==2){
cin>>a[i]>>b[i];
if(a[i]==b[i])continue;
if(D.same(p[i],a[i],b[i])){
int ok = 0,ng = i;
while(ng-ok>1){
int mid = (ok+ng)/2;
if(D.same(p[mid],a[i],b[i]))ng = mid;
else ok = mid;
}
x += b[ok+1];
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<mint> A(n);
for(int i=1;i<=q;i++){
if(t[i]==1){
int la = D2.leader(a[i]),lb = D2.leader(x);
if(D2.same(la,lb))continue;
mint tt = D2.size(a[i]);
tt *= D2.size(x);
tt *= b[i];
tt += A[la] + A[lb];
D2.merge(la,lb);
int lc = D2.leader(la);
int ld = lc^la^lb;
A[ld] = 0;
A[lc] = tt;
}
if(t[i]==2){
if(a[i]==b[i]){
cout<<0<<endl;
continue;
}
if(D.same(p[i],a[i],b[i])){
int ok = 0,ng = i;
while(ng-ok>1){
int mid = (ok+ng)/2;
if(D.same(p[mid],a[i],b[i]))ng = mid;
else ok = mid;
}
x += b[ok+1];
x %= n;
cout<<b[ok+1]<<endl;
}
else cout<<-1<<endl;
}
if(t[i]==3){
cout<<A[D2.leader(a[i])].val()<<endl;
}
if(t[i]==4){
x += a[i];
x %= n;
}
}
return 0;
}
沙耶花