結果

問題 No.1787 Do Use Dynamic Tree
ユーザー hotman78hotman78
提出日時 2021-12-16 23:10:29
言語 C++17(gcc12)
(gcc 12.3.0 + boost 1.87.0)
結果
AC  
実行時間 7,467 ms / 10,000 ms
コード長 18,821 bytes
コンパイル時間 17,504 ms
コンパイル使用メモリ 311,328 KB
最終ジャッジ日時 2025-01-26 23:52:22
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 38
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#line 2 "cpplib/util/template.hpp"
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")
#include<bits/stdc++.h>
using namespace std;
struct __INIT__{__INIT__(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}}__INIT__;
typedef long long lint;
#define INF (1LL<<60)
#define IINF (1<<30)
#define EPS (1e-10)
#define endl ('\n')
typedef vector<lint> vec;
typedef vector<vector<lint>> mat;
typedef vector<vector<vector<lint>>> mat3;
typedef vector<string> svec;
typedef vector<vector<string>> smat;
template<typename T>using V=vector<T>;
template<typename T>using VV=V<V<T>>;
template<typename T>inline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i;f=1;}cout<<endl;}
template<typename T>inline void output2(T t){for(auto i:t)output(i);}
template<typename T>inline void debug(T t){bool f=0;for(auto i:t){cerr<<(f?" ":"")<<i;f=1;}cerr<<endl;}
template<typename T>inline void debug2(T t){for(auto i:t)debug(i);}
#define loop(n) for(long long _=0;_<(long long)(n);++_)
#define _overload4(_1,_2,_3,_4,name,...) name
#define __rep(i,a) repi(i,0,a,1)
#define _rep(i,a,b) repi(i,a,b,1)
#define repi(i,a,b,c) for(long long i=(long long)(a);i<(long long)(b);i+=c)
#define rep(...) _overload4(__VA_ARGS__,repi,_rep,__rep)(__VA_ARGS__)
#define _overload3_rev(_1,_2,_3,name,...) name
#define _rep_rev(i,a) repi_rev(i,0,a)
#define repi_rev(i,a,b) for(long long i=(long long)(b)-1;i>=(long long)(a);--i)
#define rrep(...) _overload3_rev(__VA_ARGS__,repi_rev,_rep_rev)(__VA_ARGS__)
// #define rep(i,...) for(auto i:range(__VA_ARGS__))
// #define rrep(i,...) for(auto i:reversed(range(__VA_ARGS__)))
// #define repi(i,a,b) for(lint i=lint(a);i<(lint)(b);++i)
// #define rrepi(i,a,b) for(lint i=lint(b)-1;i>=lint(a);--i)
// #define irep(i) for(lint i=0;;++i)
// inline vector<long long> range(long long n){if(n<=0)return vector<long long>();vector<long long>v(n);iota(v.begin(),v.end(),0LL);return v;}
// inline vector<long long> range(long long a,long long b){if(b<=a)return vector<long long>();vector<long long>v(b-a);iota(v.begin(),v.end(),a
    );return v;}
// inline vector<long long> range(long long a,long long b,long long c){if((b-a+c-1)/c<=0)return vector<long long>();vector<long long>v((b-a+c-1)/c
    );for(int i=0;i<(int)v.size();++i)v[i]=i?v[i-1]+c:a;return v;}
// template<typename T>inline T reversed(T v){reverse(v.begin(),v.end());return v;}
#define all(n) begin(n),end(n)
template<typename T,typename E>bool chmin(T& s,const E& t){bool res=s>t;s=min<T>(s,t);return res;}
template<typename T,typename E>bool chmax(T& s,const E& t){bool res=s<t;s=max<T>(s,t);return res;}
const string ds="DRUL";
const vector<lint> dx={1,0,-1,0,1,1,-1,-1};
const vector<lint> dy={0,1,0,-1,1,-1,1,-1};
#define SUM(v) accumulate(all(v),0LL)
#if __cplusplus>=201703L
template<typename T,typename ...Args>auto make_vector(T x,int arg,Args ...args){if constexpr(sizeof...(args)==0)return vector<T>(arg,x);else
        return vector(arg,make_vector<T>(x,args...));}
#endif
#define extrep(v,...) for(auto v:__MAKE_MAT__({__VA_ARGS__}))
#define bit(n,a) ((n>>a)&1)
vector<vector<long long>> __MAKE_MAT__(vector<long long> v){if(v.empty())return vector<vector<long long>>(1,vector<long long>());long long n=v.back
    ();v.pop_back();vector<vector<long long>> ret;vector<vector<long long>> tmp=__MAKE_MAT__(v);for(auto e:tmp)for(long long i=0;i<n;++i){ret
    .push_back(e);ret.back().push_back(i);}return ret;}
using graph=vector<vector<int>>;
template<typename T>using graph_w=vector<vector<pair<int,T>>>;
template<typename T,typename E>ostream& operator<<(ostream& out,pair<T,E>v){out<<"("<<v.first<<","<<v.second<<")";return out;}
#if __cplusplus>=201703L
constexpr inline long long powll(long long a,long long b){long long res=1;while(b--)res*=a;return res;}
#endif
template<typename T,typename E>pair<T,E>& operator+=(pair<T,E>&s,const pair<T,E>&t){s.first+=t.first;s.second+=t.second;return s;}
template<typename T,typename E>pair<T,E>& operator-=(pair<T,E>&s,const pair<T,E>&t){s.first-=t.first;s.second-=t.second;return s;}
template<typename T,typename E>pair<T,E> operator+(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res+=t;}
template<typename T,typename E>pair<T,E> operator-(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res-=t;}
// 128*1024*1024
#define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ =
    (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax,
    %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));
#define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);
#line 2 "main.cpp"
template<typename T,typename E,typename Compress,typename Rake,typename Rev>
class link_cut{
class rake_tree{
struct node;
using np=node*;
struct node{
unsigned long key,l,r;
T val,sum;
// E lazy;
bool rev=0;
int cnt=1,dep=0;
static const node* nil;
np ch[2]={};
np p=0;
node(unsigned long key,T val):key(key),l(key),r(key),val(val),sum(val){}
bool is_root() {
return !p||(p->ch[0]!=this&&p->ch[1]!=this);
}
};
Rake rake;
T et;
np root=nullptr;
inline int count(np t){return t?t->cnt:0;}
inline int depth(np t){return t?t->dep:0;}
np update(np t){
if(!t)return t;
t->cnt=count(t->ch[0])+1+count(t->ch[1]);
t->dep=max(depth(t->ch[0]),depth(t->ch[1]))+1;
t->l=t->ch[0]?t->ch[0]->l:t->l;
t->r=t->ch[1]?t->ch[1]->r:t->r;
t->sum=rake(rake(t->ch[0]?t->ch[0]->sum:et,t->val),t->ch[1]?t->ch[1]->sum:et);
return t;
}
void rot(np t,bool b){
np x=t->p,y=x->p;
if((x->ch[1-b]=t->ch[b]))t->ch[b]->p=x;
t->ch[b]=x,x->p=t;
update(x);update(t);
if((t->p=y)){
if(y->ch[0]==x)y->ch[0]=t;
if(y->ch[1]==x)y->ch[1]=t;
update(y);
}
}
void push(np t){
// if(t->lazy!=ee){
// if(t->ch[0])propagate(t->ch[0],t->lazy);
// if(t->ch[1])propagate(t->ch[1],t->lazy);
// t->lazy=ee;
// }
// if(t->rev){
// if(t->ch[0])toggle(t->ch[0]);
// if(t->ch[1])toggle(t->ch[1]);
// t->rev=0;
// }
}
np splay(np t){
push(t);
while(!t->is_root()){
np q=t->p;
if(q->is_root()){
push(q), push(t);
rot(t,q->ch[0]==t);
}else{
np r=q->p;
push(r), push(q), push(t);
bool b=r->ch[0]==q;
if(q->ch[1-b]==t)rot(q,b),rot(t,b);
else rot(t,1-b),rot(t,b);
}
}
return t;
}
// int lower_bound(T val,np t){
// if(!t)return 0;
// bool b=val>t->val;
// return(b?count(t->ch[0])+1:0)+lower_bound(val,t->ch[b]);
// }
// int upper_bound(T val,np t){
// if(!t)return 0;
// bool b=val>=t->val;
// return(b?count(t->ch[0])+1:0)+upper_bound(val,t->ch[b]);
// }
// T find_by_order(T idx,np t){
// if(idx==count(t->ch[0]))return t->val;
// bool b=idx>count(t->ch[0]);
// return find_by_order(idx-(b?count(t->ch[0])+1:0),t->ch[b]);
// }
public:
rake_tree(Rake rake,T et):rake(rake),et(et){}
std::pair<np,np> split(np t,unsigned long key){
if(!t)return make_pair(nullptr,nullptr);
bool b=key>t->key;
auto s=split(t->ch[b],key);
if(t->ch[b])t->ch[b]->p=0;
t->ch[b]=b?s.first:s.second;
if(t->ch[b])t->ch[b]->p=t;
return b?make_pair(update(t),s.second):make_pair(s.first,update(t));
}
std::pair<np,np> split(unsigned long key){
return split(root,key);
}
np merge(np s,np t){
if(!s)return t;
if(!t)return s;
while(s->ch[1])s=s->ch[1];
splay(s);splay(t);
s->ch[1]=t;
t->p=s;
update(s);
return s;
}
void insert(unsigned long key,T val){
auto [s,t]=split(key);
root=merge(s,merge(new node(key,val),t));
}
void erase(unsigned long key){
auto [s,t]=split(key);
while(t->ch[0])t=t->ch[0];
splay(t);
assert(t->key==key);
if(t->ch[1])t->ch[1]->p=0;
root=merge(s,t->ch[1]);
delete(t);
}
rake_tree(T et,Rake rake):et(et),rake(rake){}
inline int size(){return count(root);}
// inline int count(T val){return upper_bound(val,root)-lower_bound(val,root);}
// inline int count(int l,int r){return lower_bound(r,root)-lower_bound(l,root);}
// inline T sum(int l,int r){return sum(l,r,root);}
inline T all_sum(){return root?root->sum:et;}
//0-indexidx
// inline T operator[](T idx){return find_by_order(idx,root);}
// //x/s[lower_bound(x)]x
// inline int lower_bound(T x){return lower_bound(x,root);}
// //x/s[upper_bound(x)]x
// inline int upper_bound(T x){return upper_bound(x,root);}
};
public:
struct node;
using np=node*;
struct node{
np ch[2]={};
np p=0;
int key;
unsigned long id,id_sum,rake_node_id_sum=0;
T val,path_sum,subtree_sum,subtree_sum2,subtree_sum_rev,subtree_sum2_rev;
rake_tree rake_node;
bool rev=0;
// E lazy=ee;
int sz=1;
// node(){}
inline unsigned long rnd() {
static unsigned long x=123456789, y=362436069, z=521288629, w=88675123;
unsigned long t=(x^(x<<11));
x=y; y=z; z=w;
return ( w=(w^(w>>19))^(t^(t>>8)) );
}
node(unsigned long key,T et,Rake rake):key(key),val(et),path_sum(et),subtree_sum(et),subtree_sum2(et),subtree_sum_rev(et),subtree_sum2_rev(et
            ),rake_node(rake,et){
id=id_sum=rnd();
}
bool is_root(){
return !p||(p->ch[0]!=this&&p->ch[1]!=this);
}
};
std::vector<np>p;
Compress compress;
Rake rake;
Rev rev;
T et;
E ee;
int size(np t){return t?t->sz:0;}
void update(np t){
t->sz=size(t->ch[0])+1+size(t->ch[1]);
// t->l=t->ch[0]?t->ch[0]->l:t->l;
// t->r=t->ch[1]?t->ch[1]->r:t->r;
t->id_sum=(t->id^(t->ch[0]?t->ch[0]->id_sum:0)^(t->ch[1]?t->ch[1]->id_sum:0)^(t->rake_node_id_sum));
// subtree_sum t, subtree_sum2 t->ch[0]->ch[0]->...
// t->path_sum=compress(t->ch[0]?t->ch[0]->path_sum:et,compress(t->val,t->ch[1]?t->ch[1]->path_sum:et));
t->subtree_sum=compress(t->val,rake(t->rake_node.all_sum(),t->ch[1]?t->ch[1]->subtree_sum2:et));
t->subtree_sum2=compress(t->ch[0]?t->ch[0]->subtree_sum2:et,t->subtree_sum);
t->subtree_sum_rev=compress(t->val,rake(t->rake_node.all_sum(),t->ch[0]?t->ch[0]->subtree_sum2_rev:et));
t->subtree_sum2_rev=compress(t->ch[1]?t->ch[1]->subtree_sum2_rev:et,t->subtree_sum_rev);
}
void rot(np t,bool b){
np x=t->p,y=x->p;
push(x), push(t);
if((x->ch[1-b]=t->ch[b]))t->ch[b]->p=x;
t->ch[b]=x,x->p=t;
update(x);update(t);
if((t->p=y)){
if(y->ch[0]==x)y->ch[0]=t;
if(y->ch[1]==x)y->ch[1]=t;
update(y);
}
}
void splay(np t){
push(t);
while(!t->is_root()){
np q=t->p;
if(q->is_root()){
push(q), push(t);
rot(t,q->ch[0]==t);
}else{
np r=q->p;
push(r), push(q), push(t);
bool b=r->ch[0]==q;
if(q->ch[1-b]==t)rot(q,b),rot(t,b);
else rot(t,1-b),rot(t,b);
}
}
}
void propagate(np t,E x){
// t->lazy=h(t->lazy,x);
// t->key=g(t->key,x,1);
// t->sum=g(t->sum,x,t->sz);
}
void set_propagate(np t,E x){
expose(t);
propagate(t,x);
push(t);
}
void push(np t){
// if(t->lazy!=ee){
// if(t->ch[0])propagate(t->ch[0],t->lazy);
// if(t->ch[1])propagate(t->ch[1],t->lazy);
// t->lazy=ee;
// }
if(t->rev){
if(t->ch[0])toggle(t->ch[0]);
if(t->ch[1])toggle(t->ch[1]);
t->rev=0;
}
}
np expose(np t){
np rp=nullptr;
for(np cur=t;cur;cur=cur->p){
splay(cur);
if(cur->ch[1]){
// toggle(cur->ch[1]);
// push(cur->ch[1]);
// cerr<<"+"<<cur->ch[1]->subtree_sum2<<endl;
// cerr<<cur->rake_node.all_sum()<<endl;
// cerr<<"+"<<cur->ch[1]->id_sum<<endl;
cur->rake_node_id_sum^=cur->ch[1]->id_sum;
cur->rake_node.insert(cur->ch[1]->id_sum,cur->ch[1]->subtree_sum2);
// cerr<<cur->rake_node.all_sum()<<endl;
}
cur->ch[1]=rp;
if(cur->ch[1]){
cur->ch[1]->p=cur;
// cerr<<"-"<<cur->ch[1]->subtree_sum2<<endl;
// cerr<<cur->rake_node.all_sum()<<endl;
// cerr<<"-"<<cur->ch[1]->id_sum<<endl;
push(cur->ch[1]);
cur->rake_node_id_sum^=cur->ch[1]->id_sum;
cur->rake_node.erase(cur->ch[1]->id_sum);
// cerr<<cur->rake_node.all_sum()<<endl;
}
update(cur);
rp=cur;
}
splay(t);
return rp;
}
vector<int>get_path(np x){
vector<int>vs;
auto dfs=[&](auto dfs,np cur){
if(!cur)return;
dfs(dfs,cur->ch[1]);
vs.push_back(cur->key);
dfs(dfs,cur->ch[0]);
};
expose(x);
dfs(dfs,x);
return vs;
}
void link(np ch,np par){
expose(ch);
expose(par);
ch->p=par;
par->ch[1]=ch;
update(par);
}
void cut(np ch){
expose(ch);
np par=ch->ch[0];
ch->ch[0]=nullptr;
par->p=nullptr;
update(ch);
}
void toggle(np t){
assert(t);
swap(t->ch[0],t->ch[1]);
swap(t->subtree_sum,t->subtree_sum_rev);
swap(t->subtree_sum2,t->subtree_sum2_rev);
t->rev^=1;
}
void evert(np t){
expose(t);
toggle(t);
push(t);
}
np get_root(np x){
expose(x);
while(x->ch[0]){
push(x);
x=x->ch[0];
}
return x;
}
public:
link_cut(int sz,Compress comp=Compress(),Rake rake=Rake(),Rev rev=Rev(),T et=T(),E ee=E()):compress(comp),rake(rake),rev(rev),et(et),ee(ee){
p.resize(sz,nullptr);
for(int i=0;i<sz;i++)p[i]=new node(i,et,rake);
}
link_cut(){}
void set_val(int t,T val) {
expose(p[t]);
p[t]->val=val;
update(p[t]);
}
T get_val(int t) {
return p[t]->val;
}
vector<int> get_path(int s,int t){
evert(p[s]);
return get_path(p[t]);
}
void path_add(int s,int t,E x){
evert(p[s]);
set_propagate(p[t],x);
}
T get_path_sum(int s,int t){
evert(p[s]);
expose(p[t]);
return p[t]->path_sum;
}
//ts
T get_subtree_sum(int s,int t){
evert(p[t]);
expose(p[s]);
return p[s]->subtree_sum;
}
void make_node(T x){
p.emplace_back(new node(p.size(),x));
}
void evert(int t){
evert(p[t]);
}
void link(int s,int t){
evert(p[s]);
link(p[s],p[t]);
}
void cut(int s,int t){
evert(p[s]);
cut(p[t]);
}
bool same(int s,int t){
return get_root(p[s])==get_root(p[t]);
}
np lca(int s,int t){
if(get_root(p[s])!=get_root(p[t]))return nullptr;
expose(p[s]);
return expose(p[t]);
}
};
int main(){
lint n;
cin>>n;
vec a(n);
rep(i,n)a[i]=i;
struct data{
bool zero;
int pos;
int far;
// l/rr/l
bool flag;
// r/l
int ch;
};
auto dif=[&](int x){
return x==-1?-1:a[x];
};
auto compress=[&](const data& s,const data& t){
if(s.zero)return t;
if(t.zero)return s;
data res;
if(s.flag&&dif(s.ch)<dif(t.pos)){
res.pos=s.pos;
res.far=t.far;
res.flag=t.flag;
res.ch=t.ch;
}else{
res.pos=s.pos;
res.far=s.far;
res.flag=0;
res.ch=-1;
}
return res;
};
auto rake=[&](const data& s,const data& t){
if(s.zero)return t;
if(t.zero){
data res=s;
res.flag=1;
res.ch=s.pos;
return res;
}
if(dif(s.pos)<dif(t.pos)){
return t;
}
else{
data res=s;
res.flag=0;
res.ch=-1;
return res;
}
};
auto rev=[&](const data& s){return s;};
const data zero=data{1,0,0,0,0};
link_cut<data,tuple<>,decltype(compress),decltype(rake),decltype(rev)>lc(n,compress,rake,rev,zero);
for(int i=0;i<n;++i){
lc.set_val(i,data{0,i,i,1,-1});
}
rep(i,n-1){
lint s,t;
cin>>s>>t;
s--;t--;
lc.link(s,t);
}
lint q;
cin>>q;
lint pre=0;
while(q--){
lint s,t;
cin>>s>>t;
s--;t--;
s=(s+pre)%n;
t=(t+pre)%n;
// cerr<<s<<" "<<t<<endl;
int tmp=a[t];
lc.expose(lc.p[t]);
a[t]=a[s];
lc.update(lc.p[t]);
lc.expose(lc.p[s]);
a[s]=tmp;
lc.update(lc.p[s]);
// cerr<<lc.p[s].ch[1]<<endl;
// cerr<<lc.get_subtree_sum(s,s).far<<lc.get_subtree_sum(s,s).flag<<endl;
cout<<(pre=lc.get_subtree_sum(s,s).far+1)<<endl;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0