博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 4010 Query on The Trees(动态树)
阅读量:6001 次
发布时间:2019-06-20

本文共 2560 字,大约阅读时间需要 8 分钟。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4010

题意:一棵树,四种操作:

(1)若x和y不在一棵树上,将x和y连边;

(2)若x和y在一棵树上,将x变成树根,将y从x树上分离;

(3)若x和y在一棵树上,将x到y路径上的所有值增加det;

(4)若x和y在一棵树上,输出x到y路径上的最大值。

思路:1操作用link维护,2操作用cut,34操作先split(x,y),然后对y做tag,并且记录路径的max值。

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 int tot,go[600005],next[600005],first[300005]; 8 int ch[600005][2],rev[600005],tag[600005],q[600005]; 9 int st[600005],mx[600005],fa[600005],v[600005]; 10 bool pd(int x){ 11 return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; 12 } 13 void insert(int x,int y){ 14 tot++;go[tot]=y;next[tot]=first[x];first[x]=tot; 15 } 16 void addedge(int x,int y){ 17 insert(x,y);insert(y,x); 18 } 19 void pushdown(int x){ 20 int l=ch[x][0],r=ch[x][1]; 21 if (rev[x]){ 22 rev[x]^=1;rev[l]^=1;rev[r]^=1; 23 std::swap(ch[x][0],ch[x][1]); 24 } 25 if (tag[x]){ 26 if (l) tag[l]+=tag[x],v[l]+=tag[x],mx[l]+=tag[x]; 27 if (r) tag[r]+=tag[x],mx[r]+=tag[x],v[r]+=tag[x]; 28 tag[x]=0; 29 } 30 } 31 void updata(int x){ 32 int l=ch[x][0],r=ch[x][1]; 33 mx[x]=std::max(v[x],std::max(mx[l],mx[r])); 34 } 35 void rotate(int x){ 36 int y=fa[x],z=fa[y],l,r; 37 if (ch[y][0]==x) l=0;else l=1;r=l^1; 38 if (!pd(y)){ 39 if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=x; 40 } 41 fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; 42 ch[y][l]=ch[x][r];ch[x][r]=y; 43 updata(y);updata(x); 44 } 45 void splay(int x){ 46 int top=0;st[++top]=x; 47 for (int i=x;!pd(i);i=fa[i]) 48 st[++top]=fa[i]; 49 for (int i=top;i;i--) 50 pushdown(st[i]); 51 while (!pd(x)){ 52 int y=fa[x],z=fa[y]; 53 if (!pd(y)){ 54 if (ch[y][0]==x^ch[z][0]==y) rotate(x); 55 else rotate(y); 56 } 57 rotate(x); 58 } 59 } 60 void access(int x){ 61 for (int t=0;x;t=x,x=fa[x]){ 62 splay(x); 63 ch[x][1]=t; 64 updata(x); 65 } 66 } 67 void makeroot(int x){ 68 access(x);splay(x);rev[x]^=1; 69 } 70 void cut(int x,int y){ 71 makeroot(x);access(y);splay(y);ch[y][0]=fa[ch[y][0]]=0;updata(y); 72 } 73 void link(int x,int y){ 74 makeroot(x); 75 fa[x]=y; 76 } 77 int find(int x){ 78 access(x);splay(x); 79 while (ch[x][0]) x=ch[x][0]; 80 return x; 81 } 82 void add(int x,int y,int val){ 83 makeroot(x);access(y);splay(y); 84 mx[y]+=val;v[y]+=val;tag[y]+=val; 85 } 86 int main(){ 87 int n,x,y,m,opt,w; 88 while (scanf("%d",&n)!=EOF){ 89 mx[0]=-2000000000; 90 for (int i=0;i<=n;i++) 91 mx[i]=tag[i]=rev[i]=v[i]=ch[i][0]=ch[i][1]=fa[i]=0; 92 memset(first,0,sizeof first);tot=0; 93 for (int i=1;i

 

转载于:https://www.cnblogs.com/qzqzgfy/p/5537899.html

你可能感兴趣的文章
XML文件解析
查看>>
我的友情链接
查看>>
UIButton如何正确调整imageView及titleLabel的位置
查看>>
mysql主从复制
查看>>
AIX 基础笔记2
查看>>
级联引用完整性约束
查看>>
Linux目录架构详解
查看>>
Add DHCP Reservations in a batch with a Script
查看>>
Service与Android系统实现(1)-- 应用程序里的Service
查看>>
用JavaScript开发的桌面应用
查看>>
curl指令的使用
查看>>
我的友情链接
查看>>
Linux常用命令—egrep及扩展正则表达式
查看>>
为什么使用xfs
查看>>
THINKPHP 结合阿里大于发送短信
查看>>
网站故障排查常用命令
查看>>
Python setdaemon守护进程
查看>>
ubuntu10.04下安装LAMP
查看>>
sendmail+tls+java
查看>>
wget 用法
查看>>