您的位置:首页 > 其它

BZOJ4129: Haruna’s Breakfast

2015-08-11 09:18 330 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=4129

  树上带修改求mex,树上带修改莫队即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=50015,maxe=100015,maxm=50015,maxb=255,maxk=20;
int n,m,ask,tim,a[maxn];
struct Tmodify{int x,v;}M[maxm];
struct Tquery{int idx,u,v,t;}Q[maxm];
int tot,now[maxn],pre[maxe],son[maxe];
void connect(int u,int v){pre[++tot]=now[u];now[u]=tot;son[tot]=v;}
void init(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i) scanf("%d",&a[i]);
for (int u,v,i=1;i<=n-1;++i){
scanf("%d%d",&u,&v);
connect(u,v);connect(v,u);
}
for (int t,u,v,i=1;i<=m;++i){
scanf("%d%d%d",&t,&u,&v);
switch (t){
case 0:M[++tim]=(Tmodify){u,v};break;
case 1:Q[++ask]=(Tquery){ask,u,v,tim};break;
}
}
}
int dep[maxn],anc[maxn][maxk];
void get_anc(int u,int f){
anc[u][0]=f;dep[u]=dep[f]+1;
for (int k=1;k<maxk;++k) anc[u][k]=anc[anc[u][k-1]][k-1];
for (int p=now[u];p;p=pre[p]) if (son[p]!=f) get_anc(son[p],u);
}
int siz1,top,cnt,stk[maxn],bel[maxn];
void get_block(int u,int f){
for (int bot=top,p=now[u];p;p=pre[p]){
if (son[p]==f) continue;get_block(son[p],u);
if (top-bot>=siz1) for (++cnt;top!=bot;bel[stk[top--]]=cnt);
}
stk[++top]=u;
}
bool cmp(Tquery a,Tquery b){
if (bel[a.u]!=bel[b.u]) return bel[a.u]<bel[b.u];
else if (bel[a.v]!=bel[b.v]) return bel[a.v]<bel[b.v];
else return a.t<b.t;
}
void prepare(){
siz1=pow(n,0.67);
get_anc(1,0);get_block(1,0);
while (top) bel[stk[top--]]=cnt;
for (int i=1;i<=ask;++i) if (bel[Q[i].u]>bel[Q[i].v]) swap(Q[i].u,Q[i].v);
sort(Q+1,Q+ask+1,cmp);
}
bool exist[maxn];
int num,siz2,ans[maxm],bl[maxb],br[maxb],have[maxb],idx[maxn],sum[maxn];
void xor_node(int u){
if (exist[u]){if (a[u]<=n) if (!--sum[a[u]]) --have[idx[a[u]]];}
else if (a[u]<=n) if (!sum[a[u]]++) ++have[idx[a[u]]];
exist[u]^=1;
}
void xor_path(int u,int v){
if (dep[u]<dep[v]) swap(u,v);
while (dep[u]!=dep[v]){xor_node(u);u=anc[u][0];}
while (u!=v){xor_node(u);xor_node(v);u=anc[u][0];v=anc[v][0];}
}
void modify(int t){
int x=M[t].x,v=M[t].v;
if (exist[x]){
if (a[x]<=n) if (!--sum[a[x]]) --have[idx[a[x]]];
if (v<=n) if (!sum[v]++) ++have[idx[v]];
}
swap(M[t].v,a[x]);
}
void move_time(int ever,int now){
for (int i=ever+1;i<=now;++i) modify(i);
for (int i=ever;i>=now+1;--i) modify(i);
}
int lca(int u,int v){
if (dep[u]<dep[v]) swap(u,v);
for (int h=dep[u]-dep[v],i=0;h;h>>=1,++i) if (h&1) u=anc[u][i];
for (int k=maxk-1;k>=0;--k) if (anc[u][k]!=anc[v][k]){u=anc[u][k];v=anc[v][k];}
return u==v?u:anc[u][0];
}
int get_ans(){
int pos,res;
for (pos=0;have[pos]==siz2;++pos);
for (res=bl[pos];sum[res];++res);
return res;
}
void solve(int k){
xor_path(Q[k-1].u,Q[k].u);
xor_path(Q[k-1].v,Q[k].v);
move_time(Q[k-1].t,Q[k].t);
int x=lca(Q[k].u,Q[k].v);
xor_node(x);ans[Q[k].idx]=get_ans();xor_node(x);
}
void work(){
prepare();siz2=sqrt(n);
for (int j,i=0;i<=n;i=j,++num){
for (j=i;j-i+1<=siz2&&j<=n;++j) idx[j]=num;
bl[num]=i;br[num]=j-1;
}
for (int i=1;i<=ask;++i) solve(i);
for (int i=1;i<=ask;++i) printf("%d\n",ans[i]);
}
int main(){
init();
work();
return 0;
}


my code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: