BZOJ4129 Haruna’s Breakfast
2016-05-27 20:58
323 查看
带修改树上莫队加分块-_-
带修改莫队:把修改和查询分别存起来,查询按x所在块为第一关键字,y所在块为第二关键字,时间为第三关键字排序,修改按时间排序,然后再扫查询的时候每次走完x和y再走时间,该更改的更改,该回滚的回滚,块的大小取n^(2/3),复杂度为n^(5/3)
树上分块:维护一个栈,维护子树内没有块的点,深搜,回溯的时候压栈,当栈里元素大于块下界的时候分一块
树上莫队:刚开始使得L和R都在根,没有点在莫队里(-_-这个表述真蛋疼),假设要转移到x,y,设x和L的lca为l1,y和R的lca为l2,把x到l1,L到l1,y到l2,R到l2上的点的状态都取反(l1和l2不取反),然后把L,R设为x,y,把lca(L,R)的状态取反,记录解,再把lca(L,R)的状态取反
然后这道题再对答案分一下块,每次查询的时候从小到大,查这块满不满,不满就进块里查第一个没有的就好了
带修改莫队:把修改和查询分别存起来,查询按x所在块为第一关键字,y所在块为第二关键字,时间为第三关键字排序,修改按时间排序,然后再扫查询的时候每次走完x和y再走时间,该更改的更改,该回滚的回滚,块的大小取n^(2/3),复杂度为n^(5/3)
树上分块:维护一个栈,维护子树内没有块的点,深搜,回溯的时候压栈,当栈里元素大于块下界的时候分一块
树上莫队:刚开始使得L和R都在根,没有点在莫队里(-_-这个表述真蛋疼),假设要转移到x,y,设x和L的lca为l1,y和R的lca为l2,把x到l1,L到l1,y到l2,R到l2上的点的状态都取反(l1和l2不取反),然后把L,R设为x,y,把lca(L,R)的状态取反,记录解,再把lca(L,R)的状态取反
然后这道题再对答案分一下块,每次查询的时候从小到大,查这块满不满,不满就进块里查第一个没有的就好了
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<iomanip> #include<vector> #include<stack> #include<queue> #include<set> #include<bitset> #include<map> using namespace std; #define MAXN 200010 #define MAXM 50010 #define ll long long #define eps 1e-8 #define INF 1000000000 #define MOD 1000000007 struct vec{ int to; int fro; }; struct que{ int x; int y; int t; int v; }; struct ch{ int x; int t; int v; int vv; }; vec mp[MAXN]; int tai[MAXN],cnt; int fa[MAXN][20],dep[MAXN]; int bel[MAXN],tot; int a[MAXN],ta[MAXN]; int ans[MAXN]; que q[MAXN]; ch c[MAXN]; int st[MAXN],ed[MAXN],p[MAXN]; int ct[MAXN],tt[MAXN]; int L,R,wzh; int n,m,Q,C; int MX,SZ; int tls[MAXN],tln,mx; int s[MAXN],tp; bool vis[MAXN]; map<int,int>h; int g[MAXN]; bool operator <(que x,que y){ return bel[x.x]!=bel[y.x]?bel[x.x]<bel[y.x]:bel[x.y]!=bel[y.y]?bel[x.y]<bel[y.y]:x.t<y.t; } bool operator <(ch x,ch y){ return x.t<y.t; } inline void be(int x,int y){ mp[++cnt].to=y; mp[cnt].fro=tai[x]; tai[x]=cnt; } inline void bde(int x,int y){ be(x,y); be(y,x); } void dfs(int x){ int i,t,y,j; dep[x]=dep[fa[x][1]]+1; int now=tp; for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; if(!dep[y]){ for(j=1,t=x;t;j++){ fa[y][j]=t; t=fa[t][j]; } dfs(y); if(tp-now>MX){ tot++; while(tp>now){ bel[s[tp--]]=tot; } } } } s[++tp]=x; if(x==1){ tot++; while(tp){ bel[s[tp--]]=tot; } } } int lca(int x,int y){ int i; if(dep[x]<dep[y]){ swap(x,y); } for(i=19;i;i--){ if(dep[fa[x][i]]>=dep[y]){ x=fa[x][i]; } } for(i=19;i;i--){ if(fa[x][i]!=fa[y][i]){ x=fa[x][i]; y=fa[y][i]; } } return x==y?x:fa[x][1]; } void del(int x){ if(!--ct[x]){ tt[p[x]]--; } } void add(int x){ if(!ct[x]++){ tt[p[x]]++; } } void rev(int x){ if(vis[x]){ del(a[x]); vis[x]=0; }else{ add(a[x]); vis[x]=1; } } void change(int x,int y){ if(vis[x]){ del(a[x]); a[x]=y; add(a[x]); }else{ a[x]=y; } } int cal(){ int i; for(i=1;;i++){ if(tt[i]!=ed[i]-st[i]+1){ break; } } for(i=st[i];;i++){ if(!ct[i]){ return i; } } } int main(){ int i,x,y,o; scanf("%d%d",&n,&m); MX=pow(1.0*n*n,1.0/3); tls[++tln]=0; for(i=1;i<=n;i++){ scanf("%d",&a[i]); ta[i]=a[i]; tls[++tln]=a[i]; tls[++tln]=a[i]+1; } for(i=1;i<n;i++){ scanf("%d%d",&x,&y); bde(x,y); } dfs(1); for(i=1;i<=m;i++){ scanf("%d%d%d",&o,&x,&y); if(o==0){ C++; c[C].x=x; c[C].t=i; c[C].v=y; c[C].vv=a[x]; tls[++tln]=y; tls[++tln]=y+1; a[x]=y; }else{ Q++; q[Q].x=x; q[Q].y=y; q[Q].t=i; q[Q].v=Q; } } for(i=1;i<=n;i++){ a[i]=ta[i]; } tls[0]=-1; sort(tls+1,tls+tln+1); for(i=1;i<=tln;i++){ if(tls[i]!=tls[i-1]){ h[tls[i]]=++mx; g[mx]=tls[i]; } } SZ=sqrt(mx); for(i=1;i<=mx;i++){ p[i]=(i-1)/SZ+1; if(!st[p[i]]){ st[p[i]]=i; } ed[p[i]]=i; } for(i=1;i<=C;i++){ c[i].v=h[c[i].v]; c[i].vv=h[c[i].vv]; } for(i=1;i<=n;i++){ a[i]=h[a[i]]; } sort(q+1,q+Q+1); sort(c+1,c+C+1); L=1,R=1; wzh=0; for(i=1;i<=Q;i++){ int l1=lca(q[i].x,L); int l2=lca(q[i].y,R); for(x=L;x!=l1;x=fa[x][1]){ rev(x); } for(x=q[i].x;x!=l1;x=fa[x][1]){ rev(x); } for(x=R;x!=l2;x=fa[x][1]){ rev(x); } for(x=q[i].y;x!=l2;x=fa[x][1]){ rev(x); } L=q[i].x; R=q[i].y; int l=lca(L,R); rev(l); while(wzh<C&&c[wzh+1].t<=q[i].t){ wzh++; change(c[wzh].x,c[wzh].v); } while(wzh&&c[wzh].t>=q[i].t){ change(c[wzh].x,c[wzh].vv); wzh--; } ans[q[i].v]=cal(); rev(l); } for(i=1;i<=Q;i++){ printf("%d\n",g[ans[i]]); } return 0; } /* 5 1 4 4 4 3 3 2 1 3 2 4 2 5 2 1 3 3 */
相关文章推荐
- poj1312dfs基础
- 《Word排版艺术》读后感,兼谈LaTeX
- 【NOIP2013模拟】Freda的传呼机 题解+代码
- LaTeX:Figures, Tables, and Equations 插入图表和公式
- datasnap 的线程池(转)
- [转]LevelDB原理探究与代码分析
- java中的泛型
- 阶段总结一
- java 读取txt,java读取大文件
- 第一个spring冲刺心得及感想
- C语言中32个关键字
- 动态规划1004
- 5.26NOI模拟赛2
- 【bzoj1500】【NOI2005】维修数列
- AVL树C实现
- 字符串比较问题的内部分析
- ajax和js验证用户登录
- 打包静态库.a文件的方法(ar,ranlib,nm命令介绍)
- LaTeX 的对参考文献的处理
- java期末设计(十三周)