BZOJ 4129 Haruna’s Breakfast
2017-04-20 09:54
344 查看
同糖果公园,直接树分块套带修莫队即可。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> #include<cmath> using namespace std; const int maxn = 505000; vector<int> f[maxn],g[maxn]; int val[maxn],deep[maxn],fa[maxn],son[maxn],top[maxn],sz[maxn],dfn[maxn],q[maxn],pre[maxn]; int pos[maxn],res[maxn],num[maxn],belong[maxn],n,m,x,y,blo,blonum,dfs_clock,Top,ans; struct oper{ int x,y,id,op,t; }T[maxn]; struct change{ int x,y,t,pre,id; }F[maxn]; bool vis[maxn]; bool operator < (oper a,oper b){ if(belong[a.x]==belong[b.x]&&belong[a.y]==belong[b.y]) return a.t<b.t; else if(belong[a.x]==belong[b.x]) return belong[a.y]<belong[b.y]; else return belong[a.x]<belong[b.x]; } int dfs1(int x,int fath,int dep){ int size=0; dfn[x]=++dfs_clock;deep[x]=dep; sz[x]=1;son[x]=0;fa[x]=fath; for(int i=0;i<f[x].size();i++){ int v=f[x][i]; if(v==fath) continue; size+=dfs1(v,x,dep+1); sz[x]+=sz[v]; if(size>=blo){ blonum++; for(int k=1;k<=size;k++) belong[q[Top--]]=blonum; size=0; } if(sz[son[x]]<sz[v]) son[x]=v; } q[++Top]=x; return size+1; } void dfs2(int x,int tp){ top[x]=tp; if(son[x]) dfs2(son[x],tp); for(int i=0;i<f[x].size();i++){ int v=f[x][i]; if(v==fa[x]||v==son[x]) continue; dfs2(v,v); } } int lca(int a,int b){ while(top[a]!=top[b]){ if(deep[top[a]]<deep[top[b]]) swap(a,b); a=fa[top[a]]; } return deep[a]>deep[b] ? b : a; } void reverse(int x){ if(vis[x]){ if(val[x]>maxn) return; num[val[x]]--;if(!num[val[x]]){ if(ans>val[x]) ans=val[x]; } } else{ if(val[x]>maxn) return; num[val[x]]++;if(ans==val[x]){ while(num[ans]) ans++; } } vis[x]^=1; } void change(int x,int y){ if(vis[x]){ reverse(x);val[x]=y;reverse(x); }else val[x]=y; } void solve(int x,int y){ while(x!=y){ if(deep[x]>deep[y]) reverse(x),x=fa[x]; else reverse(y),y=fa[y]; } } int main() { scanf("%d%d",&n,&m); blo=pow(n,2.0/3)*0.5; for(int i=1;i<=n;i++) scanf("%d",&val[i]),pre[i]=val[i]; for(int i=1;i<n;i++){ scanf("%d%d",&x,&y); f[x].push_back(y); f[y].push_back(x); } dfs1(1,1,0); dfs2(1,1); while(Top) belong [q[Top--]]=blonum; int c1=0,c2=0,typ; for(int i=1;i<=m;i++){ scanf("%d%d%d",&typ,&x,&y); if(!typ){ c1++; F[c1].x=x;F[c1].y=y;F[c1].pre=pre[x];pre[x]=y; }else{ c2++; if(dfn[x]>dfn[y]) swap(x,y); T[c2].x=x;T[c2].y=y;T[c2].id=c2;T[c2].t=c1; } } sort(T+1,T+1+c2); for(int i=1;i<=T[1].t;i++) change(F[i].x,F[i].y); int t=lca(T[1].x,T[1].y); solve(T[1].x,T[1].y); reverse(t);res[T[1].id]=ans;reverse(t); // cout<<T[1].id<<endl; // for(int j=1;j<=10;j++) cout<<vis[j]<<" "; // cout<<endl; for(int i=2;i<=c2;i++) { // cout<<T[i].id<<" "<<i<<" "<<T[i].x<<" "<<T[i].y<<" "<<T[i].t<<endl; for(int j=T[i-1].t+1;j<=T[i].t;j++) change(F[j].x,F[j].y); for(int j=T[i-1].t;j>T[i].t;j--) change(F[j].x,F[j].pre); solve(T[i-1].x,T[i].x);solve(T[i-1].y,T[i].y); // cout<<T[i-1].y<<" "<<T[i].y<<" "<<deep[T[i-1].y]<<" "<<deep[T[i].y]<<endl; // for(int j=1;j<=10;j++) cout<<vis[j]<<" "; // cout<<endl; int t=lca(T[i].x,T[i].y); reverse(t);res[T[i].id]=ans;reverse(t); } for(int i=1;i<=c2;i++) printf("%d\n",res[i]); return 0; }
相关文章推荐
- 【树上莫队】【带修莫队】【权值分块】bzoj4129 Haruna’s Breakfast
- BZOJ4129 Haruna’s Breakfast
- [BZOJ4129]Haruna’s Breakfast(树上带修改莫队+权值分块)
- 【bzoj4129】Haruna’s Breakfast 树上莫队+分块
- [bzoj 4129]Haruna’s Breakfast
- [BZOJ4129]Haruna’s Breakfast
- [bzoj4129] Haruna’s Breakfast
- BZOJ4129 : Haruna’s Breakfast
- bzoj 4129: Haruna's Breakfast
- bzoj 4129: Haruna’s Breakfast (带修改树上莫队+分块)
- [BZOJ4129]Haruna’s Breakfast(树上莫队+分块)
- bzoj 4129: Haruna’s Breakfast
- [bzoj4129] Haruna’s Breakfast
- BZOJ4129: Haruna’s Breakfast
- BZOJ 4129 Haruna’s Breakfast (分块 + 带修莫队)
- BZOJ 4129 Haruna’s Breakfast 带修改树上莫队+分块
- [BZOJ4129]Haruna’s Breakfast(树上带修改莫队+分块)
- [BZOJ4129]-Haruna’s Breakfast-带修改树上莫队+分块
- 【BZOJ4129】Haruna’s Breakfast(树上莫队)
- bzoj4129 Haruna’s Breakfast