[BZOJ]4129: Haruna’s Breakfast 树上带修改莫队+分块
2017-08-07 13:49
323 查看
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值。
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值。
题解:
mex问题我们可以容易对数字进行分块+莫队从而解决,详情见BZOJ3585(权限题)。到了树上,我们可以考虑用树上莫队,又由于有修改,我们用带修改莫队。做法都差不多,我是参考neither_nor的代码的。有几个地方要注意一下:1、树上的分块,每块的大小是n23,我也不知道为什么……2、从(L,R)到(X,Y)的处理,看一下代码,脑补一下就差不多了。代码:
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; const int maxn=50010; struct Edge{int y,next;}e[maxn*2]; int last[maxn],len=0; void ins(int x,int y) { int t=++len; e[t].y=y;e[t].next=last[x];last[x]=t; } int dep[maxn],fa[maxn][18]; int sta[maxn],top=0,bl[maxn],MX,cnt=0; int n,m,belong[maxn],c[maxn],block[250],l[250],r[250],vis[maxn],a[maxn]; void dfs(int x) { dep[x]=dep[fa[x][0]]+1; for(int i=1;(1<<i)<=dep[x];i++)fa[x][i]=fa[fa[x][i-1]][i-1]; int now=top; for(int i=last[x];i;i=e[i].next) { int y=e[i].y; if(y==fa[x][0])continue; fa[y][0]=x;dfs(y); if(top-now>MX) { cnt++; while(top>now)bl[sta[top--]]=cnt; } } sta[++top]=x; if(x==1) { cnt++; while(top)bl[sta[top--]]=cnt; } } int LCA(int x,int y) { if(dep[x]<dep[y])swap(x,y);//x jump for(int i=17;i>=0;i--) if((1<<i)<=dep[x]-dep[y])x=fa[x][i]; if(x==y)return x; for(int i=17;i>=0;i--) if(dep[x]>=(1<<i)&&fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i]; return fa[x][0]; } void add(int x) { if(a[x]>n)return; c[a[x]]++; if(c[a[x]]==1)block[belong[a[x]]]++; } void del(int x) { if(a[x]>n)return; c[a[x]]--; if(!c[a[x]])block[belong[a[x]]]--; } void change(int x,int y) { if(vis[x])del(x),a[x]=y,add(x); else a[x]=y; } void rev(int x) { if(vis[x])vis[x]=0,del(x); else vis[x]=1,add(x); } int calc() { if(!c[0])return 0; int i; for(i=1;i<=belong ;i++) if(block[i]!=r[i]-l[i]+1)break; for(int j=l[i];j<=r[i];j++) if(!c[j])return j; } struct Modify{int x,y,pre;}A[maxn]; struct Query{int x,y,time,id;}B[maxn]; bool cmp(Query a,Query b) { if(bl[a.x]!=bl[b.x])return bl[a.x]<bl[b.x]; if(bl[a.y]!=bl[b.y])return bl[a.y]<bl[b.y]; return a.time<b.time; } int la=0,lb=0,ans[maxn],yl[maxn]; int main() { memset(block,0,sizeof(block)); memset(c,0,sizeof(c)); scanf("%d%d",&n,&m); MX=(int)pow(1.0*n*n,1.0/3); for(int i=1;i<=n;i++)scanf("%d",&a[i]),yl[i]=a[i]; int sq=(int)sqrt(n); for(int i=1;i<=n;i++)//对数字进行分块 { belong[i]=(i-1)/sq+1; int w=belong[i]; if(!l[w])l[w]=i; r[w]=i; } for(int i=1;i<n;i++ 107b6 ) { int u,v; scanf("%d%d",&u,&v); ins(u,v);ins(v,u); } dfs(1); for(int i=1;i<=m;i++) { int op,x,y; scanf("%d%d%d",&op,&x,&y); if(op==0) { A[++la].x=x;A[la].y=y; A[la].pre=a[x]; a[x]=y; } else { B[++lb].x=x;B[lb].y=y; B[lb].time=la;B[lb].id=lb; } } sort(B+1,B+1+lb,cmp); for(int i=1;i<=n;i++)a[i]=yl[i]; int L=1,R=1;B[0].time=0; for(int i=1;i<=lb;i++) { int l1=LCA(B[i].x,L); int l2=LCA(B[i].y,R); for(int x=L;x!=l1;x=fa[x][0])rev(x); for(int x=B[i].x;x!=l1;x=fa[x][0])rev(x); for(int x=R;x!=l2;x=fa[x][0])rev(x); for(int x=B[i].y;x!=l2;x=fa[x][0])rev(x); L=B[i].x;R=B[i].y; int l=LCA(L,R); rev(l); for(int j=B[i-1].time+1;j<=B[i].time;j++)change(A[j].x,A[j].y); for(int j=B[i-1].time;j>B[i].time;j--)change(A[j].x,A[j].pre); ans[B[i].id]=calc(); rev(l); } for(int i=1;i<=lb;i++) printf("%d\n",ans[i]); }
相关文章推荐
- BZOJ 4129 Haruna’s Breakfast - 带修树上莫队+分块
- BZOJ 4129 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,树上带修莫队+权值分块求mex
- BZOJ 4129: Haruna’s Breakfast [树上莫队 分块]
- 【BZOJ】4129: Haruna’s Breakfast 树分块+带修改莫队算法
- [BZOJ4129]Haruna’s Breakfast(树上带修改莫队+权值分块)
- BZOJ 4129 Haruna’s Breakfast 树上莫队
- [BZOJ4129]-Haruna’s Breakfast-带修改树上莫队+分块
- bzoj 4129: Haruna’s Breakfast (带修改树上莫队+分块)
- 树上(带修改)莫队算法-- bzoj4129 && bzoj3757
- 【BZOJ4129】Haruna’s Breakfast(树上莫队)
- 【树上莫队】【带修莫队】【权值分块】bzoj4129 Haruna’s Breakfast
- 【bzoj4129】Haruna’s Breakfast 树上莫队+分块
- [BZOJ4129]Haruna’s Breakfast(树上莫队+分块)
- bzoj3052 糖果公园 树上莫队+修改