1663: Tree

Time Limit: 5 Sec  Memory Limit:
128 MB

Submit: 26  Solved: 11

[Submit][

id=1663">Status][

pid=1663">Web
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(树链剖分)的更多相关文章

  1. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

  2. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  3. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

  4. 【BZOJ-4353】Play with tree 树链剖分

    4353: Play with tree Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 31  Solved: 19[Submit][Status][ ...

  5. SPOJ Query on a tree 树链剖分 水题

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  6. poj 3237 Tree 树链剖分

    题目链接:http://poj.org/problem?id=3237 You are given a tree with N nodes. The tree’s nodes are numbered ...

  7. Codeforces Round #200 (Div. 1) D Water Tree 树链剖分 or dfs序

    Water Tree 给出一棵树,有三种操作: 1 x:把以x为子树的节点全部置为1 2 x:把x以及他的所有祖先全部置为0 3 x:询问节点x的值 分析: 昨晚看完题,马上想到直接树链剖分,在记录时 ...

  8. poj 3237 Tree 树链剖分+线段树

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  9. 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 ...

随机推荐

  1. Netbeans 中部署运行Webservice出错

      错误如下 at java.lang.StackTraceElement at public java.lang.StackTraceElement[] java.lang.Throwable.ge ...

  2. Android activity中单击返回键或home键彻底退出应用

    @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_BAC ...

  3. Charles 抓包的工具

    下面是整个链接. http://www.winshy.com/2013/08/something_about_charlesproxy/?utm_source=rss Charles:移动端抓包工具安 ...

  4. 【IntellJ IDEA】idea上 实现了Serializable接口,要自动生成serialVersionUID的方法

    需要点进setting ->搜索Inspections-->右侧选择java 下拉 进入Serialization issue--->勾选Serializable class wit ...

  5. ubuntu live cd修复grub引导项

    1. 通过Ubuntu Live CD(安装盘,选择try Ubuntu)进入Ubuntu系统 打开终端,依次进行如下操作: 1. sudo fdisk -l 出现如下界面: 2. 然后会看到,有好多 ...

  6. textureView

    textureView是用来访问texture的一部分的 cubemap 和 mipmap会用到这个 for(face =0;face<6;face++) setrendertarget(tex ...

  7. 【JUnit】Junit命令行执行、参数化执行、Main方法执行

    参考资料: main方法执行:http://stackoverflow.com/questions/2543912/how-do-i-run-junit-tests-from-inside-my-ja ...

  8. PHP empty()函数说明---用了N遍了就是记不住

    从表面上看,很容易误解empty()函数是判断字符串是否为空的函数,其实并不是,我也因此吃了很多亏. empty()函数是用来测试变量是否已经配置.若变量已存在.非空字符串或者非零,则返回 false ...

  9. bat 同步windows系统时间

    需要使用管理员权限运行 net start w32timew32tm /config /updatew32tm /resync /rediscovernet stop w32timepause

  10. DBCC MEMORYSTATUS

    内存管理器 输出的第一节是内存管理器.此部分将显示 SQL Server 的总内存消耗. Memory Manager KB ------------------------------ ------ ...