题目来源: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. Django一些开发经验

    总结一些 Django 开发的小经验.先说一些最最基础的吧. 使用 virtualenv 隔离开发环境 使用 pip 管理项目依赖,主要就是一个小技巧,使用 pip freeze > requi ...

  2. join和 Daemon守护线程

    一.前言 一个程序至少有一个主线程,主线程启动子线程后,它们之间并没有隶属关系.主线程和子线程执行是并行的,相互独立.主线程执行完毕后默认不等子线程执行结束就接着往下走了,如果有其他程序就会运行另外的 ...

  3. [BZOJ1758][WC2010]重建计划(点分治+单调队列)

    点分治,对于每个分治中心,考虑求出经过它的符合长度条件的链的最大权值和. 从分治中心dfs下去取出所有链,为了防止两条链属于同一个子树,我们一个子树一个子树地处理. 用s1[i]记录目前分治中心伸下去 ...

  4. bzoj 2961

    根据“点在圆内”关系,列出点P(x0,y0)在圆C(x,y)内的关系: (x-x0)^2+(y-y0)^2 <= x^2+y^2 化简得: 2*x0*x+2*y0*y >= x0^2+y0 ...

  5. Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) C. Bear and Colors 暴力

    C. Bear and Colors 题目连接: http://www.codeforces.com/contest/673/problem/C Description Bear Limak has ...

  6. hdoj 4445 Crazy Tank 物理题/枚举角度1

    Crazy TankTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  7. Python学习笔记(五)—列表的学习

    总结内容: 1.list的定义 2.list的取值 3.list数据的增加 4.list数据的删除 5.list数据的修改 6.list数据的查询 7.list方法的介绍 8.list的合并 9.多维 ...

  8. [Database] MongoDB 副本集配置

    MongoDB 副本集配置 MongoDB复制是将数据同步在多个服务器的过程. 复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性. 复制还允许您从硬 ...

  9. Leetcode 树 Populating Next Right Pointers in Each Node II

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie Populating Next Right Pointers in Each Node II ...

  10. jQuery碎语(3) 动画特效

    5.动画特效 ● 自制折叠内容块 内容块如下 <div class="module"> <div class="caption"> &l ...