hdu3966_树链剖分
近期在强化知识点深度。发现树链剖分不是非常会写了。
回想一下改动操作:
若两个点在同一条链上,则直接改动这段区间。
若不在同一条链上,改动深度较大的点到其链顶端的区间,同一时候将这个点变为他所在链顶端的父亲,循环操作直到这两个点在同一条链上。就能够用上一种方法了。
没实用LCA写是由于曾经被坑过,不但没有这样的方法好写。效率也不太让人惬意。
主要是对另外一种情况怎样写有所遗忘。写道模版再给自己提个醒。
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<string.h>
- #include<math.h>
- #include<algorithm>
- #include<vector>
- #include<queue>
- using namespace std;
- #define MAXN 50005
- int n,m,q;
- vector<int> map[MAXN];
- int size[MAXN],fa[MAXN],son[MAXN],val[MAXN],tid[MAXN],_tid[MAXN],dep[MAXN],top[MAXN];
- int cnt;
- struct node
- {
- int l,r,val;
- }tree[MAXN<<2];
- void dfs1(int s,int f,int d)
- {
- size[s]=1;
- fa[s]=f;
- dep[s]=d;
- int len=map[s].size();
- for(int i=0;i<len;i++)
- {
- int e=map[s][i];
- if(e==f)continue;
- dfs1(e,s,d+1);
- size[s]+=size[e];
- if(son[s]==0)
- son[s]=e;
- else if(size[son[s]]<size[e])
- son[s]=e;
- }
- }
- void dfs2(int s,int t)
- {
- tid[s]=++cnt;
- _tid[cnt]=s;
- top[s]=t;
- if(son[s]!=0)
- dfs2(son[s],t);
- int len=map[s].size();
- for(int i=0;i<len;i++)
- {
- int e=map[s][i];
- if(e!=fa[s] && e!=son[s])
- dfs2(e,e);
- }
- }
- void build(int l,int r,int now)
- {
- tree[now].l=l;
- tree[now].r=r;
- tree[now].val=0;
- if(l==r)
- {
- tree[now].val=val[_tid[l]];
- return ;
- }
- int mid=(l+r)>>1;
- build(l,mid,now<<1);
- build(mid+1,r,now<<1|1);
- }
- void down(int now)
- {
- tree[now<<1].val+=tree[now].val;
- tree[now<<1|1].val+=tree[now].val;
- tree[now].val=0;
- }
- void update(int l,int r,int now,int num)
- {
- if(l==tree[now].l && r==tree[now].r)
- {
- tree[now].val+=num;
- return ;
- }
- if(tree[now].val)
- down(now);
- int mid=(tree[now].l+tree[now].r)>>1;
- if(r<=mid)
- update(l,r,now<<1,num);
- else if(l>mid)
- update(l,r,now<<1|1,num);
- else
- {
- update(l,mid,now<<1,num);
- update(mid+1,r,now<<1|1,num);
- }
- }
- void change(int s,int e,int num)
- {
- while(top[s]!=top[e])
- {
- if(dep[top[s]]<dep[top[e]])
- swap(s,e);
- update(tid[top[s]],tid[s],1,num);
- s=fa[top[s]];
- }
- if(dep[s]>dep[e])
- swap(s,e);
- update(tid[s],tid[e],1,num);
- }
- int query(int l,int now)
- {
- if(tree[now].l==l && tree[now].r==l)
- return tree[now].val;
- if(tree[now].val)
- down(now);
- int mid=(tree[now].l+tree[now].r)>>1;
- if(l<=mid)
- return query(l,now<<1);
- else
- return query(l,now<<1|1);
- }
- int main()
- {
- while(cin>>n>>m>>q)
- {
- memset(size,0,sizeof(size));
- memset(fa,0,sizeof(fa));
- memset(tid,0,sizeof(tid));
- memset(son,0,sizeof(son));
- cnt=0;
- for(int i=1;i<=n;i++)
- {
- scanf("%d",&val[i]);
- map[i].clear();
- }
- for(int i=1;i<n;i++)
- {
- int a,b;
- scanf("%d%d",&a,&b);
- map[a].push_back(b);
- map[b].push_back(a);
- }
- dfs1(1,-1,1);
- dfs2(1,1);
- build(1,n,1);
- while(q--)
- {
- char ch[5];
- int a,b,c;
- scanf("%s",ch);
- if(ch[0]=='Q')
- {
- scanf("%d",&a);
- printf("%d\n",query(tid[a],1));
- }
- else
- {
- scanf("%d%d%d",&a,&b,&c);
- if(ch[0]=='I')
- change(a,b,c);
- else
- change(a,b,-c);
- }
- }
- }
- }
hdu3966_树链剖分的更多相关文章
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1728 Solved: 531[Submit][Status][Discu ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)
题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...
- 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)
题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...
- 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)
题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...
- bzoj2243树链剖分+染色段数
终于做了一道不是一眼出思路的代码题(⊙o⊙) 之前没有接触过这种关于染色段数的题目(其实上课好像讲过),于是百度了一下(现在思维能力好弱) 实际上每一段有用的信息就是总共有几段和两段各是什么颜色,在开 ...
- bzoj3631树链剖分
虽然是水题1A的感觉太爽了O(∩_∩)O~ 题意相当于n-1次树上路径上每个点权值+1,最后问每个点的权值 本来想写线段树,写好了change打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
随机推荐
- EOJ 2847 路由结点
数学知识 凸N边形的对角线条数为:n(n-3)/2因为每一个交点对应两条对角线,而两条对角线又对应着一个四边形.于是焦点个数就对应四边形的个数.问题转化成由凸n边形的n个顶点取4个顶点可组成多少个四边 ...
- 常见Java集合的实现细节
1. Set和Map Set代表一种集合元素无序.集合元素不可重复的集合,Map则代表一种由多个key-value对组成的集合,Map集合类似于传统的关联数组.表面上看它们之间相似性很少,但实际上Ma ...
- canvas的自动画图
<!DOCTYPE HTML><html><body> <canvas id="myCanvas" width="200&quo ...
- maven使用杂记
maven test使用记录 运行指定的测试类: >mvn test -Dtest=[ClassName] 运行测试类中指定的方法:(这个需要maven-surefire-plugin: ...
- CentOS6.5下nginx-1.8.1.tar.gz的单节点搭建(图文详解)
不多说,直接上干货! [hadoop@djt002 local]$ su root Password: [root@djt002 local]# ll total drwxr-xr-x. root r ...
- VS2015启动显示无法访问此网站
之前启动项目发生过几次,也忘了怎么解决了,今天记录一下:将应用文件夹下的vs目录删除,重新生成解决方案后,程序正常启动. 原文链接:https://blog.csdn.net/upi2u/articl ...
- hibernate dao 公共方法
package com.dao.impl; import java.lang.reflect.ParameterizedType; import java.util.Collection; impor ...
- 【Oracle】创建角色
任务:创建角色 1)创建角色sse_role,授予create session 权限 2)创建角色tblo_role,授予CREATE PROCEDURE, CREATE SEQUENCE, CREA ...
- 开源作品-PHP写的在线文件管理工具(单文件绿色版)-SuExplorer_PHP_3_0
前言:项目开发过程中,网站一般部署到远程服务器,所以文件管理就不能和本机操作一样方便.通常文件管理是用ftp下载到本地,修改后再上传,或者远程登录到服务器进行修改.但是这些操作都依赖于复杂的第三方软件 ...
- zmodem使用方法
无论有xshell还是secureCRT连接linux的时. 默认都用一个zmodem可以帮助window和linux之间传输文件 很方便和实用的工具. 不过默认是无法使用的 需要安装lrzsz软件 ...