poj2763 树链剖分(线段树)
注意这里都是把边放到线段树中,所以lca的时候,要注意如果top[x]==top[y] && x==y 的时候已经完成了。
仔细想想边和点的不同之处!!!
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 1000000007
#define mod 100000000
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int MAXN = ;
struct node
{
int to;
int val;
int next;
}edge[MAXN*];
int a[MAXN][];
int fa[MAXN],pre[MAXN],ind,w[MAXN],top[MAXN],siz[MAXN],son[MAXN],deq[MAXN],cnt;//w[]表示它和他父亲的连线在线段树种的位置
int vis[MAXN],n,m,tree[MAXN<<];
void add(int x,int y,int z)
{
edge[ind].to = y;
edge[ind].val = z;
edge[ind].next = pre[x];
pre[x] = ind++;
}
void dfs1(int rt,int pa,int d)
{
vis[rt] = ;
siz[rt] = ;
son[rt] = -;
deq[rt] = d;
fa[rt] = pa;
for(int i = pre[rt]; i != -; i = edge[i].next){
int t = edge[i].to;
if(!vis[t]){
dfs1(t,rt,d+);
siz[rt] += siz[t];
if(siz[t] > siz[son[rt]]){
son[rt] = t;
}
}
}
}
void dfs2(int rt,int tp)
{
vis[rt] = ;
w[rt] = ++ cnt;
top[rt] = tp;
if(son[rt] != -){
dfs2(son[rt],tp);
}
for(int i = pre[rt]; i != -; i = edge[i].next){
int t = edge[i].to;
if(!vis[t] && t != son[rt]){
dfs2(t,t);
}
}
}
void pushup(int rt)
{
tree[rt] = tree[rt<<] + tree[rt<<|];
}
void updata(int p,int val,int l,int r,int rt)
{
if(l == r){
tree[rt] = val;
return ;
}
int m = (l + r) >> ;
if(m >= p){
updata(p,val,lson);
}
else {
updata(p,val,rson);
}
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L <= l && r <= R){
return tree[rt];
}
int m = (l + r) >> ;
int ans = ;
if(m >= L){
ans += query(L,R,lson);
}
if(m < R){
ans += query(L,R,rson);
}
return ans;
}
int lca(int x,int y)
{
int ans = ;
while(top[x] != top[y]){
if(deq[top[x]] < deq[top[y]]){
swap(x,y);
}
ans += query(w[top[x]],w[x],,cnt,);
x = fa[top[x]];
}
if(x == y){//同一点没有边,仔细想想这就是为什么边和点的不同地方!
return ans;
}
if(deq[x] < deq[y]){
swap(x,y);
} ans += query(w[son[y]],w[x],,cnt,);//既然top[x] == top[y]说明x 和 y在同一条重边上 所以son[y]也在该路径上
//并且是树根的孩子,又w[]表示该点和其父亲相连的点的边在线段树中的编号,
//所以需要这步,这样能得出答案。
return ans;
}
int main()
{
int s,p;
while(~scanf("%d%d%d",&n,&p,&s)){
int x,y,z;
ind = ;
memset(pre,-,sizeof(pre));
for(int i = ; i < n; i++){
scanf("%d%d%d",&a[i][],&a[i][],&a[i][]);
add(a[i][],a[i][],a[i][]);
add(a[i][],a[i][],a[i][]);
}
memset(vis,,sizeof(vis));
dfs1(,,);//求deq siz son fa cnt = ;
memset(vis,,sizeof(vis));
dfs2(,);//求top w
memset(tree,,sizeof(tree));
for(int i = ; i < n; i++){
if(deq[a[i][]] < deq[a[i][]]){//让a[i][0]在下面
swap(a[i][],a[i][]);
}
updata(w[a[i][]],a[i][],,cnt,);//将a[i][0]和他父亲相连的边插入到线段树中
}
int q;
while(p--){
scanf("%d",&q);
if(q == ){
scanf("%d",&x);
printf("%d\n",lca(s,x));
s = x;
}
else {
scanf("%d%d",&x,&y);
updata(w[a[x][]],y,,cnt,);
}
}
}
return ;
}
poj2763 树链剖分(线段树)的更多相关文章
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
随机推荐
- At least one object must implement IComparable
中文:必须至少有一个对象实现 IComparable. 序列排序时报这个错误 lstReports.OrderBy(r => new { r.DepartmentName, r.ReportNo ...
- 边工作边刷题:70天一遍leetcode: day 71-3
Two Sum I/II/III 要点:都是简单题,III就要注意如果value-num==num的情况,所以要count,并且count>1 https://repl.it/CrZG 错误点: ...
- 边工作边刷题:70天一遍leetcode: day 84-2
要点:这题是combination的应用,从左向右想比从右向左容易. 因为有结果从小到大的要求,暗示用combintion而不是permutation 其实就是从小到大验证因子,每个因子和其对称因子立 ...
- Codeforces Round #258 D Count Good Substrings --计数
题意:由a和b构成的字符串,如果压缩后变成回文串就是Good字符串.问一个字符串有几个长度为偶数和奇数的Good字串. 分析:可知,因为只有a,b两个字母,所以压缩后肯定为..ababab..这种形式 ...
- linux下查找某个目录下包含某个字符串的文件
有时候要找一些字符串,但是又不知道在哪个文件,只记得一些字符串 那么如何在linux下寻找包含某段文字的文件呢? 强大的find命令可以帮你完成不可能的任务. 比如我只记得我的程序里包含唯一的字符串“ ...
- Spring addFlashAttribute
redirectAttributes.addFlashAttribute("result",accountModel); 用这个可以绑定session 但是只能用一次,可以避免最后 ...
- 一。常用UIView的属性和方法
1.frame 控件所在的矩形框的位置和尺寸(以父控件的左上角为坐标原点) 2.bounds 控件 控件所在的矩形框的位置和尺寸(以自己的左上角为坐标原点,所以bounds的x/y一般为0) 3.ce ...
- 3016 质子撞击炮 II
3016 质子撞击炮 II 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description [抱歉数据错误~~已修 ...
- AD域的安装
AD域的安装 初始化设置,改计算机名字dcserver,改静态ip,改dns指向自己. dcpromo,执行后自动装了dns. 装完后检查 1,本地用户没了 2,dns指向自己 3,dns记录是否 ...
- C语言 百炼成钢16
//题目46:海滩上有一堆桃子,五只猴子来分.第一只猴子把这堆桃子凭据分为五份,多了一个,这只 //猴子把多的一个扔入海中,拿走了一份.第二只猴子把剩下的桃子又平均分成五份,又多了 //一个,它同样把 ...