List wants to travel

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 429    Accepted Submission(s): 92

Problem Description
A boy named List who is perfect in English. Now he wants to travel and he is making a plan. But the cost of living in same citie always changes. Now he wants to know how many different kinds of continuous same cost he has to pay for living between two cities. Can you help him? (He is so lazy to do this by himself.)
 
Input
There are multiple cases. The first line contains two positive numbers N and M(N (N<=40000) where N is the amount of cities and M (M<=50000)) is the amount of operations.Then N-1 lines where each line have 3 integers a b and c, representing that there is a bidirectionoal road between city a and city b, and the cost is c.(a != b and c <= 100000). Then there are M lines of operation. For example, "Change a b c" means changing all the costs of the road which are passed by him when he travels from city a to city b to c. "Query a b" means he wants you to tell him how many different kinds of continuous same cost he has to pay traveling from city a to city b.(if a == b, the cost is 0).
 
Output
He insure you that there is exactly one route between every two different cities.
 
Sample Input
9 3
1 2 2
2 3 1
1 7 2
1 4 2
3 5 2
3 6 1
5 8 2
5 9 3
Query 1 8
Change 2 6 3
Query 1 6
 
Sample Output
3
2
 
Source
/*
hdu 5893 (树链剖分+合并) problem:
1.update:将a->b的边权设置为c
2.query:求a->b的连续边权的个数
222333 -> 2 22112->3 solve:
主要是查询的意思不是很懂. how many different kinds of continuous same cost
以为不同还要分长度,数值大小什么的。 于是没怎么想
结果后来发现是求区间中有多少个连续的子区间 - -. 感觉很僵
update直接用一个标记解决
query的时候, 维护区间左右端点的值以合并区间,合并的时候注意维护子区间的数量
而且树链剖分时 在合并链的时候也要进行判断什么的.
update的u == v的时候最好判断一下, 否则查询son[u] -> v会有问题
我们只有一个重链,可能有很多的轻链,query的 u == v时就是轻链合并的情况.
总体都是线段树的思路 hhh-2016-09-19 22:36:11
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#define lson i<<1
#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define key_val ch[ch[root][1]][0]
using namespace std;
const int maxn = 200100;
const int inf = 0x3f3f3f3f;
int head[maxn],tot,pos,son[maxn];
int top[maxn],fp[maxn],fa[maxn],dep[maxn],num[maxn],p[maxn];
int n;
int a[maxn];
struct Edge
{
int to,next;
int w;
} edge[maxn<<2]; void ini()
{
tot = 0,pos = 1;
clr(head,-1),clr(son,-1);
clr(a,0);
} void add_edge(int u,int v,int w)
{
edge[tot].to = v,edge[tot].next = head[u],edge[tot].w = w,head[u] = tot++;
} void dfs1(int u,int pre,int d)
{
// cout << u << " " <<pre <<" " <<d <<endl;
dep[u] = d;
fa[u] = pre,num[u] = 1;
for(int i = head[u]; ~i; i = edge[i].next)
{
int v = edge[i].to;
if(v != pre)
{
a[v] = edge[i].w;
dfs1(v,u,d+1);
num[u] += num[v];
if(son[u] == -1 || num[v] > num[son[u]])
son[u] = v;
}
}
} void getpos(int u,int sp)
{
top[u] = sp;
p[u] = pos++;
fp[p[u]] = u;
if(son[u] == -1)return ;
getpos(son[u],sp);
for(int i = head[u]; ~i ; i = edge[i].next)
{
int v = edge[i].to;
if(v != son[u] && v != fa[u])
getpos(v,v);
}
} struct node
{
int l,r,mid;
int ls,rs,same;
ll num ;
} tree[maxn << 2]; void push_up(int i)
{ if(tree[lson].rs == tree[rson].ls )
{
tree[i].num = tree[lson].num + tree[rson].num -1;
}
else
tree[i].num =tree[lson].num + tree[rson].num;
tree[i].ls = tree[lson].ls;
tree[i].rs = tree[rson].rs;
} void build(int i,int l,int r)
{
tree[i].l = l,tree[i].r = r;
tree[i].mid=(l+r) >>1;
tree[i].same = inf;
tree[i].num = tree[i].ls = tree[i].rs = 0;
if(l == r)
{
tree[i].ls = tree[i].rs = a[fp[l]];
tree[i].num = 1;
// cout << fp[l] <<" " << a[fp[l]] <<endl;
return;
}
build(lson,l,tree[i].mid);
build(rson,tree[i].mid+1,r);
push_up(i);
}
void make_same(int i,int val)
{
tree[i].same = val;
tree[i].num = 1;
tree[i].ls = tree[i].rs = val;
}
void push_down(int i)
{
if(tree[i].same != inf)
{
make_same(lson,tree[i].same);
make_same(rson,tree[i].same);
tree[i].same = inf;
}
} void update_area(int i,int l,int r,int val)
{
if(tree[i].l >= l && tree[i].r <= r)
{
tree[i].same = val;
tree[i].num = 1;
tree[i].ls = tree[i].rs = val;
return ;
}
push_down(i);
int mid = tree[i].mid;
if(l <= mid)
update_area(lson,l,r,val);
if(r > mid)
update_area(rson,l,r,val);
push_up(i);
} ll query(int i,int l,int r,int &tls,int &trs)
{
if(tree[i].l >= l && tree[i].r <= r)
{
if(tree[i].l == l)
tls = tree[i].ls;
if(tree[i].r == r)
trs = tree[i].rs;
return tree[i].num ;
}
push_down(i);
int mid = tree[i].mid ;
ll ans = 0;
if(r <= mid)
ans = query(lson,l,r,tls,trs);
else if(l > mid)
ans = query(rson,l,r,tls,trs);
else
{
int tls1,tls2,trs1,trs2;
ll t1 = query(lson,l,mid,tls1,trs1);
ll t2 = query(rson,mid+1,r,tls2,trs2);
ans = t1 + t2;
if(tree[lson].rs == tree[rson].ls)
{
ans --;
}
tls = tls1,trs = trs2;
}
push_up(i);
return ans;
} void update_same(int u,int v,int val)
{
int f1 = top[u],f2 = top[v];
while(f1 != f2)
{
if(dep[f1] < dep[f2])
{
swap(f1,f2),swap(u,v);
}
update_area(1,p[f1],p[u],val);
u = fa[f1],f1 = top[u];
}
if(u == v)
return ;
if(dep[u] > dep[v]) swap(u,v);
update_area(1,p[son[u]],p[v],val);
} ll query_dif(int u,int v)
{
int f1 = top[u],f2 = top[v];
int ls1,rs1,ls2,rs2;
ls1 = rs1 = ls2 = rs2 = inf;
int tls1,trs1,tls2,trs2;
int fi1 = 1,fi2 = 1;
ll ans = 0;
while(f1 != f2)
{
if(dep[f1] > dep[f2])
{
ans += query(1,p[f1],p[u],tls1,trs1);
if(trs1 == ls1)
ans--;
ls1 = tls1;
if(fi1)
{
rs1 = trs1;
fi1 = 0;
}
u = fa[f1],f1 = top[u];
}
else
{
ans += query(1,p[f2],p[v],tls2,trs2);
if(trs2 == ls2)
ans--;
ls2 = tls2;
if(fi2)
{
rs2 = trs2;
fi2 = 0;
}
v = fa[f2],f2 = top[v];
}
}
if(u == v)
{
if(tls1 == tls2)
ans --;
return ans;
}
if(dep[u] > dep[v])
{
ans += query(1,p[son[v]],p[u],tls1,trs1);
if(trs1 == ls1)
ans--;
if(tls1 == ls2)
ans --;
}
else
{
ans += query(1,p[son[u]],p[v],tls2,trs2);
if(trs2 == ls2)
ans--;
if(tls2 == ls1)
ans--;
}
return ans;
}
char str[10];
int main()
{
// freopen("in.txt","r",stdin);
int a,b,c;
int m,u,v,w;
while(scanf("%d%d",&n,&m) != EOF)
{
ini();
for(int i =1; i <n; i++)
{
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
add_edge(v,u,w);
}
dfs1(1,0,0);
getpos(1,1);
build(1,1,pos-1);
// cout << pos -1 <<endl;
for(int i = 1; i <= m; i++)
{
scanf("%s",str);
scanf("%d%d",&a,&b);
if(str[0] == 'C')
{
scanf("%d",&c);
update_same(a,b,c);
}
else
{
if(a == b)
printf("0\n");
else
printf("%I64d\n",query_dif(a,b));
}
}
}
return 0;
}

  

hdu 5893 (树链剖分+合并)的更多相关文章

  1. hdu 5052 树链剖分

    Yaoge’s maximum profit Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  2. hdu 4897 树链剖分(重轻链)

    Little Devil I Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  3. hdu 5274 树链剖分

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  4. HDU 5052 /// 树链剖分+线段树区间合并

    题目大意: 给定n (表示树有n个结点) 接下来n行给定n个点的点权(在这个点上买鸡或者卖鸡的价钱就是点权) 接下来n-1行每行给定 x y 表示x结点和y结点之间有一条边 给定q (表示有q个询问) ...

  5. HDU 3966 (树链剖分+线段树)

    Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板 ...

  6. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

  7. HDU 5242 树链剖分思想的贪心

    题意及博客 树链剖分分为2步,第一次求出深度,重儿子,第二次求出重链,用到了启发式的思想,即对于比较重的儿子,尽量去完整的维护它.类似于我们去合并两个堆,明显把小的堆逐个插入大的堆中会比大的往小的插更 ...

  8. HDU 3966 /// 树链剖分+树状数组

    题意: http://acm.hdu.edu.cn/showproblem.php?pid=3966 给一棵树,并给定各个点权的值,然后有3种操作: I x y z : 把x到y的路径上的所有点权值加 ...

  9. hdu 4729 树链剖分

    思路:这个树链剖分其实还是比较明显的.将边按权值排序后插入线段树,然后用线段树查找区间中比某个数小的数和,以及这样的数的个数.当A<=B时,就全部建新的管子. 对于A>B的情况比较 建一条 ...

随机推荐

  1. 2017-2018-1 Java演绎法 第一周 作业

    团队学习:<构建之法> [团队成员]: 学号 姓名 负责工作 20162315 马军 日常统计,项目部分代码 20162316 刘诚昊 项目部分代码,代码质量测试 20162317 袁逸灏 ...

  2. 调用WCF时,调用已超过传入消息(65536)的最大消息大小配额。若要增加配额,请使用相应绑定。

    解决方案: 其实只要在客户端配置文件中加上如下紫色粗体属性( maxReceivedMessageSize): <?xml version="1.0" encoding=&q ...

  3. C#-获取字符的GBK编码值

    public static int GetGBKValue(string key) { byte[] gbk = Encoding.GetEncoding("GBK").GetBy ...

  4. 前端基础之html-Day12

    1.web服务本质 import socket def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bi ...

  5. 新概念英语(1-49)At the butcher's

    新概念英语(1-49)At the butcher's What does Mr. Bird like? A:Do you want any meat today, Mrs. Bird? B:Yes, ...

  6. ssh整合之四单独搭建struts的运行环境

    1.导入struts的基本jar包 2.在web.xml中配置我们struts的核心控制器StrutsPrepareAndExecuteFilter <?xml version="1. ...

  7. 双击表,powerdesigner pdm 没有 comment列(no comment)

  8. tomcat增加处理线程数量

    修改server.xml <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" ma ...

  9. python KindEditord

    python 文本编辑器(KindEditord) 1.下载 官网下载:http://kindeditor.net/down.php 本地下载:http://files.cnblogs.com/fil ...

  10. Linux磁盘分区-rpm-yum

    一.磁盘分区 1.开启Linux系统前添加一块大小为15G的SCSI硬盘 2.开启系统,右击桌面,打开终端 3.为新加的硬盘分区,一个主分区大小为5G,剩余空间给扩展分区,在扩展分区上划分1个逻辑分区 ...