码迷,mamicode.com
首页 > 其他好文 > 详细

2016"百度之星" - 初赛(Astar Round2A)

时间:2016-05-21 20:26:17      阅读:563      评论:0      收藏:0      [点我收藏+]

标签:

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 }
View Code

 

 

 

 

end

2016"百度之星" - 初赛(Astar Round2A)

标签:

原文地址:http://www.cnblogs.com/gaolzzxin/p/5515419.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!