标签:
http://acm.hdu.edu.cn/showproblem.php?pid=5692
题意:给一棵树,点有权值. 操作1:询问从0点出发,经过x点(输入)的路径中,点权和最大的路径的和是多少. 操作2:将x号点的值更新为y.
思路:已0为根形成一个有根树,经过x点的所有路径的终点都在已x为根的子树中,问题相当于求一颗子树中的所有节点到0点的距离最大值,将题目的点权理解成距离.
解法:用dfs顺序对0为根的树标号,按照标号作为线段树的序号,那么某一颗子树的点在线段树的区间也是连续的了,这是一个常见的做法,参见线段树专题的树标号.
然后bfs,dfs都可以,处理出初始每个点作为终点到0点的路径和. 简单的累加. 线段树维护的是以0为起点 x为终点的路径和数组.
对于查询操作,就是线段树最大值查询. 对于更新操作, 变化量 delta= now - pre , 如果一个点值变大delta ,那么以该点为根的子树, 每个点的路径和都会增加这么多,线段树区间更新 +delta.
1 //#define debug 2 #include<cstdio> 3 #include<cstdlib> 4 #include<vector> 5 #define lrrt int L,int R,int rt 6 #define iall 1,n,1 7 #define imid int mid=(L+R)>>1 8 #define lson L,mid,rt<<1 9 #define rson mid+1,R,rt<<1|1 10 using namespace std; 11 typedef long long LL; 12 const LL inf=0x3f3f3f3f3f3f3f3fLL; 13 const int M=1e5+10; 14 int n,m; 15 struct E{ 16 int u,v; 17 }e[M]; 18 struct Q{ 19 int type,x; 20 LL y; 21 }q[M]; 22 int a[M]; 23 vector<LL> answer; 24 vector<int> g[M]; 25 struct N{ 26 int l,r; 27 }node[M]; 28 LL dist[M]; 29 int Index; 30 struct T{ 31 LL value,lazy; 32 }tree[M<<2]; 33 void init(){ 34 for(int i=0;i<n;i++){ 35 g[i].clear(); 36 } 37 for(int i=0;i<n-1;i++){ 38 int u=e[i].u; 39 int v=e[i].v; 40 g[u].push_back(v); 41 g[v].push_back(u); 42 } 43 } 44 void dfs(int u,int fa){ 45 node[u].l=++Index; 46 for(int i=0;i<g[u].size();i++){ 47 int v=g[u][i]; 48 if(v==fa) continue; 49 dfs(v,u); 50 } 51 node[u].r=Index; 52 } 53 void dfs_for_dist(int u,int fa){ 54 for(int i=0;i<g[u].size();i++){ 55 int v=g[u][i]; 56 if(v==fa) continue; 57 dist[v]+=dist[u]; 58 dfs_for_dist(v,u); 59 } 60 } 61 void build(lrrt){ 62 tree[rt].value=0; 63 tree[rt].lazy=0; 64 if(L==R) return ; 65 imid; 66 build(lson); 67 build(rson); 68 } 69 void pushup(int rt){ 70 tree[rt].value=max(tree[rt<<1].value,tree[rt<<1|1].value); 71 } 72 void pushdown(int rt){ 73 LL &z=tree[rt].lazy; 74 if(z!=0){ 75 tree[rt<<1].lazy+=z; 76 tree[rt<<1|1].lazy+=z; 77 tree[rt<<1].value+=z; 78 tree[rt<<1|1].value+=z; 79 z=0; 80 } 81 } 82 void update(int x,int y,LL z,lrrt){ 83 if(x<=L&&R<=y){ 84 tree[rt].value+=z; 85 tree[rt].lazy+=z; 86 return ; 87 } 88 imid; 89 pushdown(rt); 90 if(mid>=x) update(x,y,z,lson); 91 if(mid<y) update(x,y,z,rson); 92 pushup(rt); 93 } 94 LL query(int x,int y,lrrt){ 95 if(x<=L&&R<=y) return tree[rt].value; 96 imid; 97 pushdown(rt); 98 LL big=-inf; 99 if(mid>=x) big=max(big,query(x,y,lson)); 100 if(mid<y) big=max(big,query(x,y,rson)); 101 return big; 102 } 103 void solve(){ 104 init(); 105 Index=0; 106 dfs(0,-1); 107 for(int i=0;i<n;i++){ 108 dist[i]=a[i]; 109 } 110 dfs_for_dist(0,-1); 111 build(iall); 112 for(int i=0;i<n;i++){ 113 #ifdef debug 114 printf("i=%d l=%d r=%d\n",i,node[i].l,node[i].r); 115 #endif // debug 116 update(node[i].l,node[i].l,dist[i],iall); 117 } 118 answer.clear(); 119 for(int i=0;i<m;i++){ 120 if(q[i].type){ 121 int u=q[i].x; 122 answer.push_back(query(node[u].l,node[u].r,iall)); 123 } 124 else{ 125 int u=q[i].x; 126 LL d=q[i].y-a[u]; 127 a[u]=q[i].y; 128 update(node[u].l,node[u].r,d,iall); 129 } 130 } 131 } 132 int main(){ 133 int t; 134 while(~scanf("%d",&t)){ 135 int cas=1; 136 while(t--){ 137 scanf("%d%d",&n,&m); 138 for(int i=0;i<n-1;i++){ 139 scanf("%d%d",&e[i].u,&e[i].v); 140 } 141 for(int i=0;i<n;i++){ 142 scanf("%d",&a[i]); 143 } 144 for(int i=0;i<m;i++){ 145 scanf("%d%d",&q[i].type,&q[i].x); 146 if(q[i].type==0){ 147 scanf("%I64d",&q[i].y); 148 } 149 } 150 solve(); 151 printf("Case #%d:\n",cas++); 152 for(int i=0;i<answer.size();i++){ 153 printf("%I64d\n",answer[i]); 154 } 155 } 156 } 157 return 0; 158 }
end
2016"百度之星" - 初赛(Astar Round2A)
标签:
原文地址:http://www.cnblogs.com/gaolzzxin/p/5515419.html