CSU 1663: Tree(树链剖分)
1663: Tree
Time Limit: 5 Sec Memory Limit: id=1663">Status pid=1663">Web
128 MB
Submit: 26 Solved: 11
[Submit][
Board
Description
CSU has a lot of trees. But there is a tree which is different from the others. This one is made of weighted edges and I have three kinds of operations on it:
1. C a b: Change the weight of edge a to b (1 ≤ b ≤ 100);
2. M a b c: Multiply the weights of those edges on the path from node a to node b by c (|c|≤10, c ≠ 0);
3. Q a b: Get the sum of weights from all the edges on the path from node a to node b.
Input
There are multiple test cases.
The first line will contain a positive integer T (T ≤ 10) meaning the number of test cases.
Each test case will have an integer N (1 ≤ N ≤ 50,000) indicating the number of nodes marked from 1 to N.
Then N-1 lines followed. Each lines contains three integers a, b and c (1 ≤ a, b, c ≤ N, a ≠ b, 1 ≤ c ≤ 100) indicating the there is an edge connecting node a and node b with weight c. The edges are marked from 1 to N-1 in the order of appearance.
Then some operations followed, with one operation per line. The format is as shown in the problem description. A single letter ‘E’ indicates the end of the case. There are no more than 50,000 operations per test case.
Output
For each ‘Q’ operation, output an integer meaning the sum. The final result will never exceed 32-bit signed integer.
Sample Input
2
4
1 2 14
1 3 20
3 4 1
C 3 11
M 1 4 3
M 3 4 2
M 1 3 2
Q 2 4
M 1 4 -1
M 3 4 -2
Q 2 4
E
3
1 2 4
1 3 2
Q 2 3
C 1 7
M 2 3 2
M 1 3 5
Q 2 3
E
Sample Output
200
26
6
34
#include<stdio.h>
#include<string.h>
#define LL long long
const int N = 50005; int head[N<<1],to[N<<1],next1[N<<1],tot;
int deep[N],fath[N],son[N],num[N];
int top[N],p[N],pos; void init(){
pos=tot=0;
memset(head,-1,sizeof(head));
}
void addEdge(const int& u, const int& v){
to[tot] = v, next1[tot] = head[u], head[u] = tot++;
}
void addUndirEdge(const int& u, const int& v){
addEdge(u, v), addEdge(v, u);
} void dfs1(int u,int pre,int d){
fath[u]=pre;
deep[u]=d;
son[u]=-1;
num[u]=1;
for(int i=head[u]; i!=-1; i=next1[i]){
int v=to[i];
if(v==fath[u])continue;
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 root){
top[u]=root;
p[u]=pos++;
if(son[u]==-1)
return ;
getpos(son[u],root);
for(int i=head[u]; i!=-1; i=next1[i]){
int v=to[i];
if(v==son[u]||v==fath[u])
continue;
getpos(v,v);
}
}
struct TREE{
LL milt,sum;
}root[N*3];
LL cost[N]; void pushUp(int k){
root[k].sum=root[k<<1].sum+root[k<<1|1].sum;
}
void pushDow(int k){
if(root[k].milt!=1)
{
root[k<<1].sum*=root[k].milt;
root[k<<1].milt*=root[k].milt; root[k<<1|1].sum*=root[k].milt;
root[k<<1|1].milt*=root[k].milt;
root[k].milt=1;
}
}
void build(int l, int r, int k){
root[k].milt=1;
if(l==r){
root[k].sum=cost[l]; return ;
}
int mid=(l+r)>>1;
build(l,mid,k<<1);
build(mid+1,r,k<<1|1);
pushUp(k);
}
void update_C(int l, int r, int k, const int& id, LL c){
if(l==r){
root[k].sum=c; return ;
}
int mid=(l+r)>>1;
pushDow(k);
if(id<=mid)
update_C(l,mid,k<<1,id,c);
else
update_C(mid+1,r,k<<1|1,id,c);
pushUp(k);
}
void updata_M(int l,int r,int k,int L,int R,int M){
if(L<=l&&r<=R){
root[k].milt*=M; root[k].sum*=M;
return ;
}
pushDow(k);
int mid=(l+r)>>1;
if(L<=mid)
updata_M(l,mid,k<<1,L,R,M);
if(mid<R)
updata_M(mid+1,r,k<<1|1,L,R,M);
pushUp(k);
}
LL query(int l, int r, int k, const int& L, const int& R){
if(L<=l&&r<=R){
return root[k].sum;
}
pushDow(k);
int mid=(l+r)>>1;
LL sum=0;
if(L<=mid)
sum+=query(l,mid,k<<1,L,R);
if(mid<R)
sum+=query(mid+1,r,k<<1|1,L,R);
return sum;
}
void swp(int &u,int &v){
int tt=u; u=v; v=tt;
}
LL solve(int u,int v,int flag,LL M){
int fu=top[u], fv=top[v];
LL sum=0;
while(fu!=fv){
if(deep[fu]<deep[fv]){
swp(fu,fv); swp(u,v);
}
if(flag==0)
updata_M(1,pos,1,p[fu],p[u],M);
else
sum+=query(1,pos,1,p[fu],p[u]);
u=fath[fu]; fu=top[u];
}
if(u==v)return sum;
if(deep[u]>deep[v])
swp(u,v);
if(flag==0)
updata_M(1,pos,1,p[son[u]],p[v],M);
else
sum+=query(1,pos,1,p[son[u]],p[v]);//一不小心p[son[u]]写成了p[u]让我WA了好几次(求边权用p[son[u]],求点权用p[u])
return sum;
} struct EDG{
int u,v;
LL c;
}edg[N]; int main()
{
int n,m,a,b,T;
char op[10];
scanf("%d",&T);
while(T--){
scanf("%d",&n);
init();
for(int i=1; i<n; i++){
scanf("%d%d%lld",&edg[i].u,&edg[i].v,&edg[i].c);
addUndirEdge(edg[i].u, edg[i].v);
}
dfs1(1,1,1);
getpos(1,1);
for(int i=1; i<n; i++){
if(deep[edg[i].u]>deep[edg[i].v])
swp(edg[i].u, edg[i].v);
cost[p[edg[i].v]]=edg[i].c;
}
pos=n;
build(1,pos,1); while(1){
scanf("%s",op);
if(op[0]=='E')
break;
scanf("%d%d",&a,&b);
if(op[0]=='C')
update_C(1,pos,1,p[edg[a].v],b);
else if(op[0]=='M'){
LL M;
scanf("%lld",&M);
solve(a,b,0,M);
}
else
printf("%lld\n",solve(a,b,1,1));
}
} } /**************************************************************
Problem: 1663
User: aking2015
Language: C++
Result: Accepted
Time:2696 ms
Memory:9044 kb
****************************************************************/
CSU 1663: Tree(树链剖分)的更多相关文章
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
- POJ3237 Tree 树链剖分 边权
POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
- 【BZOJ-4353】Play with tree 树链剖分
4353: Play with tree Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 31 Solved: 19[Submit][Status][ ...
- SPOJ Query on a tree 树链剖分 水题
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- poj 3237 Tree 树链剖分
题目链接:http://poj.org/problem?id=3237 You are given a tree with N nodes. The tree’s nodes are numbered ...
- Codeforces Round #200 (Div. 1) D Water Tree 树链剖分 or dfs序
Water Tree 给出一棵树,有三种操作: 1 x:把以x为子树的节点全部置为1 2 x:把x以及他的所有祖先全部置为0 3 x:询问节点x的值 分析: 昨晚看完题,马上想到直接树链剖分,在记录时 ...
- poj 3237 Tree 树链剖分+线段树
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- 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 ...
随机推荐
- unity shadow
这东西好难找LIGHT_ATTENUATION(a) shadow 的结果就在这个衰减里,这谁能猜的着,我一点点测出来的,reference也很难找 感谢这位http://blog.csdn.net/ ...
- ISP模块之色彩增强算法--HSV空间Saturation通道调整 .
色彩增强不同于彩色图像增强,图像增强的一般处理方式为直方图均衡化等,目的是为了增强图像局部以及整体对比度.而色彩增强的目的是为了使的原有的不饱和的色彩信息变得饱和.丰富起来.对应于Photoshop里 ...
- 详细理解javascript中的强制类型转换
将值从一种类型转换为另一种类型通常称为类型转换,这是显式的情况:隐式的情况称为强制类型转换,JavaScript 中的强制类型转换总是返回标量基本类型值,如字符串.数字和布尔值. 如何理解: 类型转换 ...
- 倍福TwinCAT(贝福Beckhoff)基础教程 松下官方软件开启报错伺服未就绪怎么办
一般是伺服到电机的动力线没接好(请查看动力线接线是否正确) 更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youku.com/acetaohai123 我的在线 ...
- Tomcat、Weblogic、JBoss、GlassFish、Resin、Websphere弱口令及拿webshell方法总结 [复制链接]
1.java应用服务器 Java应用服务器主要为应用程序提供运行环境,为组件提供服务.Java 的应用服务器很多,从功能上分为两类:JSP 服务器和 Java EE 服务器.1.1 常见的Se ...
- java事务处理全解析
http://blog.csdn.net/huilangeliuxin/article/details/43446177
- EFCore & Mysql migration on Production
最好的办法是通过脚本进行生产环境数据库更新. 如: dotnet ef migration script -i -o "script.sql". 这样将会产生一个你不用在意线上版本 ...
- 杂(三)-The type java.lang.Object cannot be resolved It is indirectly referenced ...
The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files ...
- MQTT--topic
1.topic 定阅与发布必须要有主题,只有当定阅了某个主题后,才能收到相应主题的payload,才能进行通信. 2. 主题层级分隔符—“/” 主题层级分隔符使得主题名结构化.如果存在分隔符,它将 ...
- android端StarIO热敏打印机打印小票
最近在做这个热敏打印机打印小票,开始的时候在网上找资料,发现国内基本没有这方面的资料,国外也很少,在此做个打印小票的记录. 这里只记录一些关键点. 使用StarIOPort.searchPrinter ...