题目来源:POJ 2763 Housewife Wind

题意:给你一棵树 2种操作0 x 求当前点到x的最短路 然后当前的位置为x; 1 i x 将第i条边的权值置为x

思路:树上两点u, v距离为d[u]+d[v]-2*d[LCA(u,v)] 如今d数组是变化的 相应每一条边的变化 他改动的是一个区间 用时间戳处理每个点管辖的区域 然后用线段树改动 线段树的叶子节点村的是根到每个点的距离 求近期公共祖先没区别 仅仅是堕落用线段树维护d数组

各种错误 4个小时 伤不起

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 200010;
struct edge
{
int u, v, w, next;
}edges[maxn*2], e[maxn]; int E[maxn*2], H[maxn*2], I[maxn*2], L[maxn], R[maxn];
int dp[maxn*2][40];
int cnt, clock, dfn;
int first[maxn];
int a[maxn<<2];
int b[maxn];
int add[maxn<<2];
int degree[maxn];
int vis[maxn];
void AddEdge(int u, int v, int w)
{
edges[cnt].u = u;
edges[cnt].v = v;
edges[cnt].w = w;
edges[cnt].next = first[u];
first[u] = cnt++;
edges[cnt].u = v;
edges[cnt].v = u;
edges[cnt].w = w;
edges[cnt].next = first[v];
first[v] = cnt++;
}
void dfs(int u, int fa, int dep)
{
E[++clock] = u;
H[clock] = dep;
I[u] = clock;
L[u] = ++dfn;
b[dfn] = u;
for(int i = first[u]; i != -1; i = edges[i].next)
{
int v = edges[i].v;
if(v == fa)
continue;
if(vis[v])
continue;
vis[v] = true;
dfs(v, u, dep+1);
E[++clock] = u;
H[clock] = dep;
}
R[u] = dfn;
} void RMQ_init(int n)
{
for(int i = 1; i <= n; i++)
dp[i][0] = i;
for(int j = 1; (1<<j) <= n; j++)
for(int i = 1; i+(1<<j)-1 <= n; i++)
{
if(H[dp[i][j-1]] < H[dp[i+(1<<(j-1))][j-1]])
dp[i][j] = dp[i][j-1];
else
dp[i][j] = dp[i+(1<<(j-1))][j-1];
}
}
int RMQ(int l, int r)
{
l = I[l], r = I[r];
if(l > r)
swap(l, r);
int len = r-l+1, k = 0;
while((1<<k) <= len)
k++;
k--;
if(H[dp[l][k]] < H[dp[r-(1<<k)+1][k]])
return E[dp[l][k]];
else
return E[dp[r-(1<<k)+1][k]];
}
void pushdown(int rt, int l, int r)
{
int k = (r-l+1);
if(add[rt])
{
a[rt<<1] += add[rt]*(k-(k>>1));
a[rt<<1|1] += add[rt]*(k>>1);
add[rt<<1] += add[rt];
add[rt<<1|1] += add[rt];
add[rt] = 0;
}
} void build(int l, int r, int rt)
{
a[rt] = 0;
add[rt] = 0;
if(l == r)
return;
int m = (l + r) >> 1;
build(l, m, rt<<1);
build(m+1, r, rt<<1|1);
} void update(int x, int y, int l, int r, int rt, int num)
{
if(l == x && r == y)
{
a[rt] += (r-l+1)*num;
add[rt] += num;
return;
}
pushdown(rt, l, r);
int m = (l + r) >> 1;
if(y <= m)
update(x, y, l, m, rt<<1, num);
else if(x > m)
update(x, y, m+1, r, rt<<1|1, num);
else
{
update(x, m, l, m, rt<<1, num);
update(m+1, y, m+1, r, rt<<1|1, num);
}
a[rt] = a[rt<<1] + a[rt<<1|1];
} int query(int x, int l, int r, int rt)
{
if(l == r)
{
return a[rt];
}
pushdown(rt, l, r);
int m = (l + r) >> 1;
int ans = 0;
if(x <= m)
ans = query(x, l, m, rt<<1);
else
ans = query(x, m+1, r, rt<<1|1);
a[rt] = a[rt<<1] + a[rt<<1|1];
return ans;
}
int main()
{
int cas = 1;
int T;
//scanf("%d", &T);
int s, to, root, n, q;
while(scanf("%d %d %d", &n, &q, &s) != EOF)
{
memset(vis, 0, sizeof(vis));
memset(first, -1, sizeof(first));
memset(degree, 0, sizeof(degree));
clock = cnt = dfn = 0; build(1, n, 1);
//for(int i = 1; i <= n; i++)
// scanf("%d", &b[i]);
for(int i = 1; i < n; i++)
{
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
e[i].u = u;
e[i].v = v;
e[i].w = w;
AddEdge(u, v, 0);
degree[v]++;
} for(int i = 1; i <= n; i++)
if(!degree[i])
{
vis[i] = true;
dfs(i, -1, 0);
root = i;
break;
}
RMQ_init(2*n-1);
//puts("1");
for(int i = 1; i < n; i++)
{
int u = e[i].u;
int v = e[i].v;
int w = e[i].w;
//printf("***%d %d\n", L[v], R[v]);
if(L[u] < L[v])
update(L[v], R[v], 1, n, 1, w);
else
update(L[u], R[u], 1, n, 1, w);
} while(q--)
{
int x;
scanf("%d", &x);
if(!x)
{
scanf("%d", &to);
int d1 = query(L[s], 1, n, 1);
int d2 = query(L[to], 1, n, 1);
int lca = RMQ(s, to);
int d3 = query(L[lca], 1, n, 1);
//printf("***%d %d %d\n", d1, d2, d3);
printf("%d\n", d1+d2-2*d3);
//printf("%d\n", dfn);
s = to;
}
else
{
int i, w;
scanf("%d %d", &i, &w);
int x = w - e[i].w;
e[i].w = w;
int v = e[i].v;
int u = e[i].u;
if(L[u] < L[v])
update(L[v], R[v], 1, n, 1, x);
else
update(L[u], R[u], 1, n, 1, x);
}
}
}
return 0;
}

POJ 2763 Housewife Wind LCA转RMQ+时间戳+线段树成段更新的更多相关文章

  1. poj 3468 A Simple Problem with Integers 【线段树-成段更新】

    题目:id=3468" target="_blank">poj 3468 A Simple Problem with Integers 题意:给出n个数.两种操作 ...

  2. poj 3468 A Simple Problem with Integers (线段树 成段更新 加值 求和)

    题目链接 题意: 只有这两种操作 C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.&quo ...

  3. 【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记

    A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Descr ...

  4. HDU 3974 Assign the task(dfs时间戳+线段树成段更新)

    题意:给定点的上下级关系,规定假设给i分配任务a.那么他的全部下属.都停下手上的工作,開始做a. 操作 T x y 分配x任务y,C x询问x的当前任务: Sample Input 1 5 4 3 3 ...

  5. POJ 3468:A Simple Problem with Integers(线段树[成段更新])

    题意:N个数Q次操作.一共两种操作:Q l r :询问[l,r]这个区间里的数字和,C l r c: [l,r]区间里的每个数都加上c.1 ≤ N,Q ≤ 100000. 方法:线段树的成段更新.注意 ...

  6. POJ 2777 Count Color (线段树成段更新+二进制思维)

    题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...

  7. 线段树(成段更新) POJ 3468 A Simple Problem with Integers

    题目传送门 /* 线段树-成段更新:裸题,成段增减,区间求和 注意:开long long:) */ #include <cstdio> #include <iostream> ...

  8. POJ 3468 A Simple Problem with Integers (线段树成段更新)

    题目链接:http://poj.org/problem?id=3468 题意就是给你一组数据,成段累加,成段查询. 很久之前做的,复习了一下成段更新,就是在单点更新基础上多了一个懒惰标记变量.upda ...

  9. poj 3669 线段树成段更新+区间合并

    添加 lsum[ ] , rsum[ ] , msum[ ] 来记录从左到右的区间,从右到左的区间和最大的区间: #include<stdio.h> #define lson l,m,rt ...

随机推荐

  1. 在Tomcat中部署web项目的三种方式

    搬瓦工搭建SS教程 SSR免费节点:http://www.xiaokeli.me 在这里介绍在Tomcat中部署web项目的三种方式: 1.部署解包的webapp目录 2.打包的war文件 3.Man ...

  2. python使用web.py开发httpserver,解决post请求跨域问题

    使用web.py做http server开发时,遇到postman能够正常请求到数据,但是浏览器无法请求到数据,查原因之后发现是跨域请求的问题. 跨域请求,就是在浏览器窗口中,和某个服务端通过某个 “ ...

  3. 希尔排序之C++实现(初级版)

    希尔排序之C++实现(初级版) 一.源代码:希尔排序之C++实现(初级版) /*希尔排序基本思想: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组. 所有距离为d1的倍数的记录放在同一个 ...

  4. [LOJ2541][PKUWC2018]猎人杀(容斥+分治+FFT)

    https://blog.csdn.net/Maxwei_wzj/article/details/80714129 n个二项式相乘可以用分治+FFT的方法,使用空间回收可以只开log个数组. #inc ...

  5. hdu 4535 错排

    题意:错排 链接:点我 百年难得一遇大水题 #include<cstdio> #include<iostream> #include<algorithm> #inc ...

  6. java的反射机制(第三篇)

    本文转载自:http://c.biancheng.net/cpp/html/1782.html Person p=new Person();这是什么?当然是实例化一个对象了.可是这种实例化对象的方法存 ...

  7. linux下使用cronjob定时执行php脚本

    在linux中输入命令 crontab -e 然后使用vim的命令编辑打开的文件,输入 * * * * /usr/bin/php -f /home/userxxx/update.php 保存,退出,好 ...

  8. HDU 4685 Prince and Princess 二分图匹配+tarjan

    Prince and Princess 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 Description There are n pri ...

  9. Codeforces Round #131 (Div. 1) A - Game

    A. Game time limit per test 1 second memory limit per test 256 megabytes input standard input output ...

  10. Any way to start Google Chrome in headless mode?

    Any way to start Google Chrome in headless mode? - Stack Overflow Any way to start Google Chrome in ...