結果
問題 | No.529 帰省ラッシュ |
ユーザー | btk |
提出日時 | 2017-06-10 00:33:24 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 640 ms / 4,500 ms |
コード長 | 6,561 bytes |
コンパイル時間 | 1,964 ms |
コンパイル使用メモリ | 188,872 KB |
実行使用メモリ | 61,096 KB |
最終ジャッジ日時 | 2024-05-09 16:16:41 |
合計ジャッジ時間 | 7,935 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 11 ms
22,528 KB |
testcase_01 | AC | 11 ms
22,400 KB |
testcase_02 | AC | 12 ms
22,400 KB |
testcase_03 | AC | 12 ms
22,528 KB |
testcase_04 | AC | 14 ms
22,528 KB |
testcase_05 | AC | 15 ms
22,528 KB |
testcase_06 | AC | 14 ms
22,656 KB |
testcase_07 | AC | 14 ms
22,656 KB |
testcase_08 | AC | 248 ms
38,076 KB |
testcase_09 | AC | 256 ms
38,056 KB |
testcase_10 | AC | 359 ms
43,300 KB |
testcase_11 | AC | 373 ms
43,460 KB |
testcase_12 | AC | 209 ms
39,512 KB |
testcase_13 | AC | 242 ms
61,096 KB |
testcase_14 | AC | 193 ms
43,392 KB |
testcase_15 | AC | 640 ms
45,764 KB |
testcase_16 | AC | 638 ms
45,768 KB |
testcase_17 | AC | 429 ms
58,252 KB |
testcase_18 | AC | 436 ms
58,632 KB |
testcase_19 | AC | 443 ms
55,280 KB |
ソースコード
#include<bits/stdc++.h> using namespace std; typedef long long LL; #define fin "\n" #define FOR(i,bg,ed) for(int i=(bg);i<(ed);i++) #define REP(i,n) FOR(i,0,n) #define ALL(v) (v).begin(),(v).end() #define fi first #define se second #define pb push_back #define DEBUG if(0) #define REC(ret, ...) std::function<ret (__VA_ARGS__)> template <typename T>inline bool chmin(T &l,T r) {bool a=l>r;if(a)l=r;return a;} template <typename T>inline bool chmax(T &l,T r) {bool a=l<r;if(a)l=r;return a;} template <typename T> istream& operator>>(istream &is,vector<T> &v){ for(auto &it:v)is>>it; return is; } typedef vector<int> V; typedef vector<V> VV; int N,M,Q; int A[212345]; int B[212345]; int imos[112345]; V g[112345]; int X[112345]; VV Y,gg; void dfs1(int v,int p,int d){ X[v]=d; for(auto &e:g[v]){ int u=A[e]^B[e]^v; if(u==p)continue; if(X[u]<X[v]){ imos[v]++; imos[u]--; }else if(X[u]==114514){ dfs1(u,v,d+1); imos[v]+=imos[u]; } } } void dfs2(int v,int k){ X[v]=k; for(auto &e:g[v]){ int u=A[e]^B[e]^v; if(X[u]>=0)continue; if(imos[u]==0){ int nk=gg.size(); gg.pb({}); gg[k].pb(nk); dfs2(u,nk); } else{ dfs2(u,k); } } } void input(){ scanf("%d%d%d",&N,&M,&Q); REP(i,M){ scanf("%d%d",A+i,B+i); g[--A[i]].pb(i); g[--B[i]].pb(i); } } //heavy light decomposition namespace hld{ #define SZ 200010 int mem[4][SZ]; }; typedef vector<V> Graph; class HLD{ private: int *treesize; Graph *tree; public: int size,*group,*id,*par,*bg; private: void setTreeSize(int v){ treesize[v]=1; for(auto &u:(*tree)[v]){ setTreeSize(u); treesize[v]+=treesize[u]; } } void build(int v,int g,int& i){ group[v]=g; id[v]=i++; Graph &gr=(*tree); const int sz=gr[v].size(); if(sz){ int h=gr[v][0]; for(auto &u:gr[v]) if(treesize[h]<treesize[u])h=u; build(h,g,i); for(auto &u:gr[v]) if(h!=u){ par[size]=v; bg[size]=i; build(u,size++,i); } } } public: HLD(Graph *tree,int root=0) :treesize(hld::mem[0]), tree(tree),size(0), group(hld::mem[1]), id(hld::mem[0]), par(hld::mem[2]), bg(hld::mem[3]) { setTreeSize(root); int i=0; par[size]=-1; bg[size]=i; build(root,size++,i); } using P=pair<int,int>; vector<P> decomposition(int r,int c){ vector<P> res; while(group[c]!=group[r]){ res.push_back(P(bg[group[c]],id[c])); c=par[group[c]]; } res.push_back(P(id[r],id[c])); return res; } }; int n; int D[112345]; int PP[20][112345]; void dfs3(int v){ for(auto &u:gg[v]){ D[u]=D[v]+1; PP[0][u]=v; dfs3(u); } } //lcaの準備 void build_PP(){ for(int k = 0,f=1;f; k++){ f=0; for(int i = 0; i < n; i++){ if(PP[k][i]<0)PP[k+1][i]=-1; else {PP[k+1][i]=PP[k][PP[k][i]];f=1;} } } } int lca(int u,int v){ if(D[u] > D[v])swap(u,v); for(int k = 0,d;(d=D[v]-D[u]); k++)if((d >> k) & 1)v=PP[k][v]; if(u==v)return v; for(int k = 19; k >=0 ; k--){ if(PP[k][u]!=PP[k][v]){ u=PP[k][u]; v=PP[k][v]; } } return PP[0][u]; } priority_queue<int> W[512345]; typedef int ID; struct node{ ID id; }; #define isB (1<<0) #define isC (1<<1) ID mg(node& v,int l,int r){ return v.id; } ID mg(ID l,ID r){ if(W[l].top()>=W[r].top())return l; else return r; } namespace ST{ node mem[1][512345]; int cnt=0; node* get(){return mem[cnt++];} } struct seg_tree{ int size; node *seg; void init(int l,int r,int k=0){ auto &v=seg[k]; if(r-l==1){ //葉の時の処理 v.id=l; W[l].push(-1); } else if(r-l>1){ int m=(l+r)/2; init(l,m,k*2+1);init(m,r,k*2+2); v.id=mg(mg(seg[k*2+1],l,m),mg(seg[k*2+2],m,r)); } } seg_tree(int n){ size=1; while(size<n)size*=2; seg=ST::get(); init(0,size); } #define LQ a,b,k*2+1,l,m #define RQ a,b,k*2+2,m,r ID get(int a,int b,int k,int l,int r){ if(a<=l&&r<=b)return mg(seg[k],l,r); int m=(l+r)/2; bool ll=!(m<=a||b<=l); bool rr=!(r<=a||b<=m); ID ret; if(ll&&rr)ret=mg(get(LQ),get(RQ)); else if(ll)ret=get(LQ); else ret=get(RQ); seg[k].id=mg(mg(seg[k*2+1],l,m),mg(seg[k*2+2],m,r)); return ret; } ID get(int a,int b){return get(a,b,0,0,size);} void set(int a,int b,int k,int l,int r,int v){ if(r<=a||b<=l)return; if(a<=l&&r<=b){ W[l].push(v); } else{ int m=(l+r)/2; set(LQ,v); set(RQ,v); seg[k].id=mg(mg(seg[k*2+1],l,m),mg(seg[k*2+2],m,r)); } } void set(int a,int b,int val){ set(a,b,0,0,size,val); } void erase(int a,int b,int k,int l,int r){ if(r<=a||b<=l)return; if(a<=l&&r<=b){ W[l].pop(); W[l].push(-1); } else{ int m=(l+r)/2; erase(LQ); erase(RQ); seg[k].id=mg(mg(seg[k*2+1],l,m),mg(seg[k*2+2],m,r)); } } void erase(int a,int b){ erase(a,b,0,0,size); } }; int main(){ input(); REP(i,N)imos[i]=0; REP(i,N)X[i]=114514; dfs1(0,0,1); gg.pb({}); REP(i,N)X[i]=-1; X[0]=0; dfs2(0,0); n=gg.size(); //REP(i,N)cout<<X[i];cout<<endl; REP(h,20)REP(i,n)PP[h][i]=-1; dfs3(0); build_PP(); HLD hld(&gg); seg_tree st(n+10); REP(qq,Q){ int a,b,c; scanf("%d%d%d",&a,&b,&c); if(a==1){ b=X[b-1]; auto t=hld.decomposition(b,b); tie(a,b)=t[0]; st.set(a,b+1,c); } else{ b=X[b-1]; c=X[c-1]; int bc=lca(b,c); auto s=hld.decomposition(bc,b); auto t=hld.decomposition(bc,c); c=-1; for(auto &it:s){ tie(a,b)=it; int d=st.get(a,b+1); if(c==-1)c=d; else c=mg(c,d); } for(auto &it:t){ tie(a,b)=it; int d=st.get(a,b+1); if(c==-1)c=d; else c=mg(c,d); } printf("%d\n",W[c].top()); st.erase(c,c+1); } } return 0; }