bzoj4129 Haruna’s Breakfast
2017-07-11 22:32
253 查看
Description
Haruna每天都会给提督做早餐! 这天她发现早饭的食材被调皮的 Shimakaze放到了一棵树上,每个结点都有一样食材,Shimakaze要考验一下她。每个食材都有一个美味度,Shimakaze会进行两种操作:
1、修改某个结点的食材的美味度。
2、对于某条链,询问这条链的美味度集合中,最小的未出现的自然数是多少。即mex值。
请你帮帮Haruna吧。
Input
第一行包括两个整数n,m,代表树上的结点数(标号为1~n)和操作数。第二行包括n个整数a1...an,代表每个结点的食材初始的美味度。
接下来n-1行,每行包括两个整数u,v,代表树上的一条边。
接下来m 行,每行包括三个整数
0 u x 代表将结点u的食材的美味度修改为 x。
1 u v 代表询问以u,v 为端点的链的mex值。
Output
对于每次询问,输出该链的mex值。Sample Input
10 101 0 1 0 2 4 4 0 1 0
1 2
2 3
2 4
2 5
1 6
6 7
2 8
3 9
9 10
0 7 14
1 6 6
0 4 9
1 2 2
1 1 8
1 8 3
0 10 9
1 3 5
0 10 0
0 7 7
Sample Output
01
2
2
3
HINT
1<=n<=5*10^41<=m<=5*10^4
0<=ai<=10^9
正解:树上带修改莫队+分块。
我只是感觉自己可能会忘记套路然后就又做了一道题。。
这题莫队的思路还是比较显然的,问题主要是如何查询。
我们把权值按照根号$n$分块。很显然,$mex<=n$,所以我们只需要把$<=n$的数标记就行了。
查询时我们从小到大枚举每一个块,如果当前这个块没有满,那么再枚举块内的每一个元素,这样我们就能很方便地找到答案了。
//It is made by wfj_2048~ #include <algorithm> #include <iostream> #include <complex> #include <cstring> #include <cstdlib> #include <cstdio> #include <vector> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #define inf (1<<30) #define N (100010) #define il inline #define RG register #define ll long long #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) using namespace std; struct upd{ int u,v,x; }q1 ; struct que{ int i,tim,u,v; }q2 ; struct edge{ int nt,to; }g[2*N]; int head ,top ,fa ,son ,dep ,dfn ,sz ,bl ,st ,vis ,val ,sum ,la ,a ,ans ,n,m,num,Q1,Q2,Tp,Lca,cnt,Bl,totb,block; il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; } il void insert(RG int from,RG int to){ g[++num]=(edge){head[from],to},head[from]=num; return; } il int cmp(const que &a,const que &b){ if (bl[a.u]==bl[b.u] && bl[a.v]==bl[b.v]) return a.tim<b.tim; if (bl[a.u]==bl[b.u]) return bl[a.v]<bl[b.v]; return bl[a.u]<bl[b.u]; } il void dfs1(RG int x,RG int p){ dep[x]=dep[p]+1,fa[x]=p,sz[x]=1; RG int v; for (RG int i=head[x];i;i=g[i].nt){ v=g[i].to; if (v==p) continue; dfs1(v,x),sz[x]+=sz[v]; if (sz[son[x]]<=sz[v]) son[x]=v; } return; } il void dfs2(RG int x,RG int p,RG int anc){ top[x]=anc,dfn[x]=++cnt; RG int tp=Tp,v; if (son[x]) dfs2(son[x],x,anc); if (Tp-tp>block) ++totb; while (Tp-tp>block) bl[st[Tp--]]=totb; for (RG int i=head[x];i;i=g[i].nt){ v=g[i].to; if (v==p || v==son[x]) continue; tp=Tp,dfs2(v,x,v); if (Tp-tp>block) ++totb; while (Tp-tp>block) bl[st[Tp--]]=totb; } st[++Tp]=x; return; } il int lca(RG int u,RG int v){ while (top[u]!=top[v]){ if (dep[top[u]]<dep[top[v]]) swap(u,v); u=fa[top[u]]; } return dep[u]<dep[v] ? u : v; } il void update(RG int x){ if (!vis[x]){ vis[x]=1; if (a[x]>n) return; ++val[a[x]]; if (val[a[x]]==1) ++sum[a[x]/Bl]; } else{ vis[x]=0; if (a[x]>n) return; --val[a[x]]; if (!val[a[x]]) --sum[a[x]/Bl]; } return; } il void modify(RG int x,RG int v){ if (!vis[x]) a[x]=v; else update(x),a[x]=v,update(x); return; } il void change(RG int u,RG int v){ while (u!=v){ if (dep[u]>dep[v]) update(u),u=fa[u]; else update(v),v=fa[v]; } return; } il int query(){ for (RG int i=0;;++i) if (sum[i]!=Bl) for (RG int j=i*Bl;;++j) if (!val[j]) return j; } il void work(){ n=gi(),m=gi(),block=pow(n,0.6),Bl=sqrt(n); for (RG int i=1;i<=n;++i) a[i]=gi(),la[i]=a[i]; for (RG int i=1,u,v;i<n;++i) u=gi(),v=gi(),insert(u,v),insert(v,u); dfs1(1,0),dfs2(1,0,1),cnt=0; if (Tp) ++totb; while (Tp) bl[st[Tp--]]=totb; for (RG int i=1,op,u,v;i<=m;++i){ op=gi(),u=gi(),v=gi(); if (!op) q1[++Q1]=(upd){u,v,la[u]},la[u]=v; else{ if (dfn[u]>dfn[v]) swap(u,v); q2[++Q2]=(que){Q2,Q1,u,v}; } } sort(q2+1,q2+Q2+1,cmp); while (cnt<q2[1].tim) ++cnt,modify(q1[cnt].u,q1[cnt].v); change(q2[1].u,q2[1].v),Lca=lca(q2[1].u,q2[1].v); update(Lca),ans[q2[1].i]=query(),update(Lca); for (RG int i=2;i<=Q2;++i){ while (cnt<q2[i].tim) ++cnt,modify(q1[cnt].u,q1[cnt].v); while (cnt>q2[i].tim) modify(q1[cnt].u,q1[cnt].x),--cnt; change(q2[i-1].u,q2[i].u),change(q2[i-1].v,q2[i].v); Lca=lca(q2[i].u,q2[i].v),update(Lca),ans[q2[i].i]=query(),update(Lca); } for (RG int i=1;i<=Q2;++i) printf("%d\n",ans[i]); return; } int main(){ File("mex"); work(); return 0; }
相关文章推荐
- BZOJ4129: Haruna’s Breakfast
- [bzoj4129] Haruna’s Breakfast
- BZOJ 4129 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 带修改树上莫队+分块
- 【树上莫队】【带修莫队】【权值分块】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
- BZOJ 4129 Haruna’s Breakfast
- BZOJ4129 : Haruna’s Breakfast
- bzoj 4129: Haruna's Breakfast
- bzoj 4129: Haruna’s Breakfast (带修改树上莫队+分块)