[Codeforces343D]Water Tree(树链剖分)
来源:互联网 发布:js自定义弹出框 编辑:程序博客网 时间:2024/05/16 18:49
题目描述
传送门
题解
题如其名
代码
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define N 500005int n,m,dfs_clock;int tot,point[N],nxt[N*2],v[N*2];int size[N],father[N],h[N],son[N],in[N],out[N],top[N];int tr[N*4],delta[N*4]; void add(int x,int y){ ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;}void dfs_1(int x,int fa){ size[x]=1;father[x]=fa;h[x]=h[fa]+1; for (int i=point[x];i;i=nxt[i]) if (v[i]!=fa) { dfs_1(v[i],x); size[x]+=size[v[i]]; if (size[v[i]]>size[son[x]]) son[x]=v[i]; }}void dfs_2(int x,int fa){ if (x==son[fa]) top[x]=top[fa]; else top[x]=x; in[x]=++dfs_clock; if (son[x]) dfs_2(son[x],x); for (int i=point[x];i;i=nxt[i]) if (v[i]!=fa&&v[i]!=son[x]) dfs_2(v[i],x); out[x]=dfs_clock;}void pushdown(int now,int l,int r,int mid){ if (delta[now]!=-1) { tr[now<<1]=delta[now<<1]=delta[now]; tr[now<<1|1]=delta[now<<1|1]=delta[now]; delta[now]=-1; }}void change(int now,int l,int r,int lr,int rr,int opt){ int mid=(l+r)>>1; if (lr<=l&&r<=rr) { tr[now]=opt; delta[now]=opt; return; } pushdown(now,l,r,mid); if (lr<=mid) change(now<<1,l,mid,lr,rr,opt); if (mid+1<=rr) change(now<<1|1,mid+1,r,lr,rr,opt);}int query(int now,int l,int r,int x){ int mid=(l+r)>>1; if (l==r) return tr[now]; pushdown(now,l,r,mid); if (x<=mid) return query(now<<1,l,mid,x); else return query(now<<1|1,mid+1,r,x);}void CHANGE(int u,int t){ int f1=top[u],f2=top[t]; while (f1!=f2) { if (h[f1]<h[f2]) { swap(f1,f2); swap(u,t); } change(1,1,n,in[f1],in[u],0); u=father[f1]; f1=top[u]; } if (in[u]>in[t]) swap(u,t); change(1,1,n,in[u],in[t],0);}int main(){ scanf("%d",&n); for (int i=1;i<n;++i) { int x,y;scanf("%d%d",&x,&y); add(x,y),add(y,x); } dfs_1(1,0); dfs_2(1,0); memset(delta,-1,sizeof(delta)); scanf("%d",&m); for (int i=1;i<=m;++i) { int opt,x;scanf("%d%d",&opt,&x); if (opt==1) change(1,1,n,in[x],out[x],1); if (opt==2) CHANGE(1,x); if (opt==3) { int ans=query(1,1,n,in[x]); printf("%d\n",ans); } }}
手工栈
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define N 500005int n,m,dfs_clock;int tot,point[N],nxt[N*2],v[N*2];int size[N],father[N],h[N],son[N],in[N],out[N],top[N];int cur[N],stack[N];bool use[N];int tr[N*4],delta[N*4]; void add(int x,int y){ ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;}void dfs_1(){ for (int i=1;i<=n;++i) cur[i]=point[i]; size[1]=1,father[1]=0,h[1]=1; int tmp=0;stack[++tmp]=1; while (tmp) { int x=stack[tmp]; while (cur[x]&&v[cur[x]]==father[x]) cur[x]=nxt[cur[x]]; if (!cur[x]) { --tmp; if (father[x]) { size[father[x]]+=size[x]; if (size[x]>size[son[father[x]]]) son[father[x]]=x; } continue; } int vt=v[cur[x]]; size[vt]=1,father[vt]=x,h[vt]=h[x]+1; stack[++tmp]=vt; cur[x]=nxt[cur[x]]; }}void dfs_2(){ for (int i=1;i<=n;++i) cur[i]=point[i]; in[1]=++dfs_clock,top[1]=1; int tmp=0;stack[++tmp]=1; while (tmp) { int x=stack[tmp]; if (!use[x]) { use[x]=1; if (son[x]) { int vt=son[x]; in[vt]=++dfs_clock,top[vt]=top[x]; stack[++tmp]=vt; continue; } } while (cur[x]&&(v[cur[x]]==father[x]||v[cur[x]]==son[x])) cur[x]=nxt[cur[x]]; if (!cur[x]) { out[x]=dfs_clock; --tmp; continue; } int vt=v[cur[x]]; in[vt]=++dfs_clock,top[vt]=vt; stack[++tmp]=vt; cur[x]=nxt[cur[x]]; }}void pushdown(int now,int l,int r,int mid){ if (delta[now]!=-1) { tr[now<<1]=delta[now<<1]=delta[now]; tr[now<<1|1]=delta[now<<1|1]=delta[now]; delta[now]=-1; }}void change(int now,int l,int r,int lr,int rr,int opt){ int mid=(l+r)>>1; if (lr<=l&&r<=rr) { tr[now]=opt; delta[now]=opt; return; } pushdown(now,l,r,mid); if (lr<=mid) change(now<<1,l,mid,lr,rr,opt); if (mid+1<=rr) change(now<<1|1,mid+1,r,lr,rr,opt);}int query(int now,int l,int r,int x){ int mid=(l+r)>>1; if (l==r) return tr[now]; pushdown(now,l,r,mid); if (x<=mid) return query(now<<1,l,mid,x); else return query(now<<1|1,mid+1,r,x);}void CHANGE(int u,int t){ int f1=top[u],f2=top[t]; while (f1!=f2) { if (h[f1]<h[f2]) { swap(f1,f2); swap(u,t); } change(1,1,n,in[f1],in[u],0); u=father[f1]; f1=top[u]; } if (in[u]>in[t]) swap(u,t); change(1,1,n,in[u],in[t],0);}int main(){ scanf("%d",&n); for (int i=1;i<n;++i) { int x,y;scanf("%d%d",&x,&y); add(x,y),add(y,x); } dfs_1(); dfs_2(); memset(delta,-1,sizeof(delta)); scanf("%d",&m); for (int i=1;i<=m;++i) { int opt,x;scanf("%d%d",&opt,&x); if (opt==1) change(1,1,n,in[x],out[x],1); if (opt==2) CHANGE(1,x); if (opt==3) { int ans=query(1,1,n,in[x]); printf("%d\n",ans); } }}
0 0
- [Codeforces343D]Water Tree(树链剖分)
- [Codeforces343D] Water Tree 树链剖分
- codeforces 343 D. Water Tree (树链剖分)
- codeforce-343D---Water Tree (树链剖分)
- Codeforces-343D:Water Tree(树链剖分)
- CodeForces 343D Water Tree(树链剖分+dfs时间戳)
- CodeForces 343D Water Tree(树链剖分+dfs时间戳)
- Water Tree CodeForces
- CF 343D D. Water Tree(树链剖分,简单题)
- codeforces #343d water tree(dfs+线段树)
- CF343D Water Tree(线段树+dfs序+思路)
- Codeforces 343D Water Tree
- CodeForces 343D Water Tree
- codeforces 343D - Water Tree
- Codeforces 343D Water Tree
- Codeforces 343D Water Tree
- CODEFORCES 343D. Water Tree
- CodeForces 343D Water Tree
- TTY之struct console
- 【C/C++开发】值得学习的C语言开源项目
- 多线程简介
- JavaScript 发送短信案例
- Html5本地存储
- [Codeforces343D]Water Tree(树链剖分)
- centOS连不上网
- TTY之register_console
- 一个来自于知乎对数据结构的回复
- Ubuntu14.04 安装Gradle
- MyEclipse配置代码每次保存以后自动格式化
- 面试之路-TCP/IP/HTTP概述
- javaScript变量的命名规范
- UVALive 6424 Russian Dolls 贪心