POJ 1007 WZJ的数据结构(七) 树上操作

传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=983

WZJ的数据结构(七)
难度级别:C; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B

试题描述

给你一棵N个节点的无根树,每个点有一个权值(开始都是0)。请你设计一个数据结构,完成以下功能:

给你a、b、v,请将a到b路径中的节点权值都增加v(包括a点与b点)。最后输出每个节点的权值。


输入

第一行为一个正整数N。
接下来N-1行为每一条边,每行2个正整数a,b,表示有一条从a到b的边(从1开始编号)。
第N+1行为一个正整数Q,表示Q次操作。
接下来Q行为每一次询问,每行3个正整数a、b、v。

输出

最后输出每个点的权值,格式见样例。

输入示例


2 1
3 2
4 3
3 5
3 8
9 8
8 7
6 7

2 5 10 
4 6 3 
1 9 5 
2 7 10 
5 5 100

输出示例

5
25
28
3
110
3
13
18
5

其他说明

1<=N,Q<=100000

树链剖分版:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<cstring>
  7 #define PAU putchar(‘ ‘)
  8 #define ENT putchar(‘\n‘)
  9 using namespace std;
 10 const int maxn=100000+10,inf=-1u>>1,maxn3=3*maxn;
 11 struct Tedge{int x,y,w,next;}adj[maxn*2];int ms=0,fch[maxn];
 12 struct Edge{int from,to,dist;}e[maxn];
 13 void AddEdge(int u,int v,int w){adj[++ms]=(Tedge){u,v,w,fch[u]};fch[u]=ms;return;}
 14 int top[maxn],dep[maxn],son[maxn],siz[maxn],fa[maxn],sumv[maxn3],addv[maxn3],num[maxn],sz=0,ql,qr,cv,_sum,n,Q;
 15 void dfs(int u){
 16     siz[u]=1;dep[u]=dep[fa[u]]+1;
 17     for(int i=fch[u];i;i=adj[i].next){
 18         int v=adj[i].y;
 19         if(v!=fa[u]){
 20             fa[v]=u;
 21             dfs(v);
 22             if(siz[son[u]]<siz[v]) son[u]=v;
 23             siz[u]+=siz[v];
 24         }
 25     } return;
 26 }
 27 void build(int u,int tp){
 28     num[u]=++sz;top[u]=tp;
 29     if(son[u]) build(son[u],tp);
 30     for(int i=fch[u];i;i=adj[i].next){
 31         int v=adj[i].y;
 32         if(v!=fa[u]&&v!=son[u]) build(v,v);
 33     } return;
 34 }
 35 void update(int o,int L,int R){
 36     if(ql<=L&&R<=qr) addv[o]+=cv;
 37     else{
 38         int M=L+R>>1,lc=o<<1,rc=lc|1;
 39         if(ql<=M) update(lc,L,M);
 40         if(qr>M) update(rc,M+1,R);
 41     } return;
 42 }
 43 void change(int a,int b){
 44     _sum=0;
 45     int f1=top[a],f2=top[b];
 46     while(f1!=f2){
 47         if(dep[f1]<dep[f2]) swap(f1,f2),swap(a,b);
 48         ql=num[f1];qr=num[a];update(1,1,n);
 49         a=fa[f1];f1=top[a];
 50     }
 51     if(dep[a]>dep[b]) swap(a,b);
 52     ql=num[a];qr=num[b];update(1,1,n);return;//为毛不是孩子了
 53 }
 54 void clear_set(int o,int L,int R,int add){
 55     if(L==R) sumv[L]+=add+addv[o];
 56     else{
 57         int M=L+R>>1,lc=o<<1,rc=lc|1;
 58         clear_set(lc,L,M,add+addv[o]);
 59         clear_set(rc,M+1,R,add+addv[o]);
 60     } return;
 61 }
 62 inline int read(){
 63     int x=0,sig=1;char ch=getchar();
 64     while(!isdigit(ch)){if(ch==‘-‘)sig=-1;ch=getchar();}
 65     while(isdigit(ch))x=10*x+ch-‘0‘,ch=getchar();
 66     return x*=sig;
 67 }
 68 inline void write(int x){
 69     if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x;
 70     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
 71     for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return;
 72 }
 73 void init(){
 74     n=read();
 75     for(int i=1;i<n;i++){
 76         int a=read(),b=read();
 77         AddEdge(a,b,0);AddEdge(b,a,0);
 78         e[i]=(Edge){a,b,0};
 79     }
 80     dfs(1);build(1,1);
 81     for(int i=1;i<n;i++){
 82         if(dep[e[i].from]>dep[e[i].to]) swap(e[i].from,e[i].to);
 83     }
 84     return;
 85 }
 86 void work(){
 87     Q=read();
 88     while(Q--){
 89         int a=read(),b=read(),c=read();
 90         cv=c;change(a,b);
 91     }
 92     return;
 93 }
 94 void print(){
 95     clear_set(1,1,n,0);
 96     for(int i=1;i<=n;i++){
 97         write(sumv[num[i]]);ENT;
 98     }
 99     return;
100 }
101 int main(){init();work();print();return 0;}
时间: 2024-10-07 14:07:40

POJ 1007 WZJ的数据结构(七) 树上操作的相关文章

COJ 0995 WZJ的数据结构(负五)区间操作

WZJ的数据结构(负五) 难度级别:C: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大小为N的整数组A,要求你回答执行M次操作.操作分两种: 操作1:每次操作给你l,r,v三个参数,求Al至Ar中值<=v的个数. 操作2:每次操作给你l,r,v三个参数,将Al至Ar中每个数的值+v. 输入 第一行为一个正整数N.第二行为N个整数Ai.第三行为一个正整数M.接下来M行每行4个正整数t,l,

COJ 1010 WZJ的数据结构(十) 线段树区间操作

传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1001 WZJ的数据结构(十) 难度级别:D: 运行时间限制:3000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,高效执行以下过程: #include<iostream>using namespace std;const int maxn=100010;int A[maxn];int tp,ql,qr,v;int

COJ 0970 WZJ的数据结构(负三十)树分治

WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计一个数据结构,回答M次操作. 1 x v:对于树上的每一个节点y,如果将x.y在树上的距离记为d,那么将y节点的权值加上d*v. 2 x:询问节点x的权值. 输入 第一行为一个正整数N.第二行到第N行每行三个正整数ui,vi,wi.表示一条树边从ui到vi,距离为wi.第N+1行为一个正整数M.最后

COJ970 WZJ的数据结构(负三十)

WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计一个数据结构,回答M次操作. 1 x v:对于树上的每一个节点y,如果将x.y在树上的距离记为d,那么将y节点的权值加上d*v. 2 x:询问节点x的权值. 输入 第一行为一个正整数N.第二行到第N行每行三个正整数ui,vi,wi.表示一条树边从ui到vi,距离为wi.第N+1行为一个正整数M.最后

COJ 0981 WZJ的数据结构(负十九)树综合

WZJ的数据结构(负十九) 难度级别:E: 运行时间限制:15000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 WZJ的数据结构中有很多都是关于树的.这让很多练习模板的同学还要找来找去很不爽,于是WZJ跟小伙伴们一块商量如何将这些题汇拢到一块去: WZJ:为了大家简单,我规定一开始是一棵有根树. LZJ:那我一定得加上换根操作喽. XJR:链信息修改,链信息增加,链信息翻倍,维护链信息的最大,最小,总和肯定很好做. CHX:子树信息修改,子树信息增加,子树

COJ 0979 WZJ的数据结构(负二十一)

WZJ的数据结构(负二十一) 难度级别:C: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你实现一个数据结构,完成这样的功能: 给你一个N个点的图,初始状态无边. 每次加入一条双向边(u,v,w),若加入后没有构成一棵生成树,输出“Not Yet”,否则输出当前最小生成树的权值. 输入 第一行两个正整数N,M.表示有N个点M个操作.接下来M行每行三个正整数u,v,w. 输出 每次加入一条双向边(u,v,w),若加入后没有构成一棵生成

COJ 0967 WZJ的数据结构(负三十三)

WZJ的数据结构(负三十三) 难度级别:E: 运行时间限制:7000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大小为N的整数组A,要求你回答执行N次操作.操作分两种: 操作1:每次操作给你l,r,v三个参数,求Al至Ar中值<=v的个数. 操作2:每次操作给你l,r,v三个参数,将Al至Ar所有数的值设为v. 输入 第一行为一个正整数N.第二行为N个整数Ai.接下来N行每行4个正整数t,l,r,v.若t=2表

COJ969 WZJ的数据结构(负三十一)

WZJ的数据结构(负三十一) 难度级别:D: 运行时间限制:3000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 A国有两个主基站,供给全国的资源.定义一个主基站能覆盖的范围为:以该主基站为圆心,半径为r的圆(包括边界).如果一个子基站能被一个主基站覆盖,则它是激活的.有N个事件,事件分两种:1.新建一个坐标位于(x,y)的子基站. 2.给出两个主基站的半径:r1.r2.询问处于非激活状态的子基站个数. 输入 第一行是四个正整数:x1.y1.x2.y2.表示

COJ WZJ的数据结构(负十八)splay_tree的天堂

WZJ的数据结构(负十八) 难度级别:E: 运行时间限制:100000ms: 运行空间限制:700KB: 代码长度限制:2000000B 试题描述 对于前一段样例: 输入 输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目. 第2行包含N个数字,描述初始时的数列. 以下M行,每行一条命令,格式参见问题描述中的表格.为了考察垃圾回收的使用,我们精心准备了多组数据... 输出 对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字