Snacks

Snacks

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5692

dfs序+线段树

这道题涉及到对整棵树的值修改,考虑将树状结构用dfs序转化成线性结构,将树的修改转化为区间修改以降低时间复杂度(之前组队赛的时候遇到一道类似的没调出来...代码能力太缺乏了...)

代码如下:

  1 #include<cstdio>
  2 #include<vector>
  3 #include<iostream>
  4 #include<cstring>
  5 #pragma comment(linker, "/STACK:1024000000,1024000000")
  6 #define LL long long
  7 #define N 100100
  8 #define lson (x<<1)
  9 #define rson (x<<1|1)
 10 #define mid ((l+r)>>1)
 11 using namespace std;
 12 struct node{
 13     LL sum,lazy;
 14 }a[N<<2];
 15 LL val[N];
 16 int L[N],R[N];
 17 LL spre[N];
 18 int index;
 19 bool vis[N];
 20 vector<int>e[N];
 21 void init(){
 22     //for(int i=0;i<N;++i)e[i].clear();
 23     //memset(a,0,sizeof(a));
 24     memset(vis,0,sizeof(vis));
 25     memset(L,0,sizeof(L));
 26     memset(R,0,sizeof(R));
 27     memset(val,0,sizeof(val));
 28     memset(spre,0,sizeof(spre));
 29     index=0;
 30 }
 31 void dfs(int num,LL v){
 32     vis[num]=1;
 33     ++index;
 34     L[num]=index;
 35     for(LL i=0;i<e[num].size();i++)
 36         if(!vis[e[num][i]])dfs(e[num][i],v+val[e[num][i]]);
 37     e[num].clear();
 38     spre[L[num]]=v;
 39     R[num]=index;
 40 }
 41 void push_up(int x){
 42     a[x].sum=max(a[lson].sum,a[rson].sum);
 43 }
 44 void push_down(int x){
 45     a[rson].sum+=a[x].lazy;
 46     a[rson].lazy+=a[x].lazy;
 47     a[lson].sum+=a[x].lazy;
 48     a[lson].lazy+=a[x].lazy;
 49     a[x].lazy=0;
 50 }
 51 void build(int x,int l,int r){
 52     a[x].lazy=a[x].sum=0;
 53     if(l==r){
 54         a[x].sum=spre[l];
 55         return;
 56     }
 57     build(lson,l,mid);
 58     build(rson,mid+1,r);
 59     push_up(x);
 60 }
 61 void add(int x,int l,int r,int cl,int cr,LL v){
 62     if(cl<=l&&r<=cr){
 63         a[x].sum+=v;
 64         a[x].lazy+=v;
 65         return;
 66     }
 67     if(a[x].lazy!=0)push_down(x);/**except this!!!**/
 68     if(cl<=mid)add(lson,l,mid,cl,cr,v);
 69     if(mid<cr)add(rson,mid+1,r,cl,cr,v);
 70     push_up(x);
 71 }
 72 LL query(int x,int l,int r,int ql,int qr){
 73     if(ql<=l&&r<=qr)return a[x].sum;
 74     if(a[x].lazy!=0)push_down(x);
 75     LL temp=-(LL)1000000000000000000;
 76     if(ql<=mid)temp=max(temp,query(lson,l,mid,ql,qr));
 77     if(mid<qr)temp=max(temp,query(rson,mid+1,r,ql,qr));
 78     return temp;
 79 }
 80 int main(void){
 81     int T,n,m;
 82     scanf("%d",&T);
 83     for(int i=1;i<=T;++i){
 84       /*if(i==10)while(1);
 85         WA when i==10*/
 86         init();
 87         scanf("%d%d",&n,&m);
 88         for(int j=1;j<n;++j){
 89             int x,y;
 90             scanf("%d%d",&x,&y);x++,y++;
 91             e[x].push_back(y);
 92             e[y].push_back(x);
 93         }
 94         for(int j=1;j<=n;++j)
 95             scanf("%I64d",&val[j]);
 96         dfs(1,val[1]);
 97         build(1,1,n);
 98         printf("Case #%d:\n",i);
 99         while(m--){
100             int type;
101             scanf("%d",&type);
102             if(type==0){
103                 int x,v;
104                 scanf("%d%d",&x,&v);x++;
105                 LL diff=(LL)v-val[x];
106                 val[x]=(LL)v;
107                 add(1,1,n,L[x],R[x],diff);
108             }else if(type==1){
109                 int x;
110                 scanf("%d",&x);x++;
111                 LL temp=query(1,1,n,L[x],R[x]);
112                 printf("%I64d\n",temp);
113             }
114         }
115     }
116     return 0;
117 }
时间: 2024-10-27 12:50:16

Snacks的相关文章

hdu 5692 Snacks(dfs时间戳+线段树)

Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2165    Accepted Submission(s): 513 Problem Description 百度科技园内有n个零食机,零食机之间通过n?1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值v会时常发

hdu 5692 Snacks 线段树+dfs

Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1295    Accepted Submission(s): 302 Problem Description 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值v会时常发

HDU5692 Snacks DFS序 线段树

题目 HDU5692 Snacks Problem Description 百度科技园内有n个零食机,零食机之间通过n?1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化.小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次.另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机. 为小度熊规划一个路线,使得路线上的价值总和最大. Input 输入数据第一行是一个整数T(T≤10),表示有T组测试数

hdu-5692 Snacks(dfs序+线段树)

题目链接: Snacks Problem Description 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化.小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次.另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机. 为小度熊规划一个路线,使得路线上的价值总和最大. Input 输入数据第一行是一个整数T(T≤10),表示有TT组测试数据. 对

D. Cow and Snacks 并查集

D. Cow and Snacks 题意:有n种小吃,m个人,每个人有两种喜欢的小吃,当一个人遇到两种自己都喜欢的小吃,可以都吃掉,问在最优的吃小吃顺序下,不能吃到自己喜欢的小吃的人数最少是多少? 题解:把n种小吃当作n个点,m个人当作m条边,每个连通图里面第一个吃的人,一定是可以吃两种自己喜欢的小吃.每次判断这条边是否在已有的联通图里面,对已经在连通图里面的边,是一定不能吃到小吃,若不在连通图里面,则一定可以吃到小吃,用cnt统计可以吃到小吃的人数,最后m-cnt就是答案 #include<i

HDU 5692 Snacks

题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=5692] 题意:一棵树,每个节点有权值,有两种操作:1.修改某个点的权值,2.求以x根的子树中的节点到根的权值和的最大值. 题解:DFS序:对点进行重新编号,每个子树中的所有的节点的编号是连续的.映射到线段树上,进行区间修改,区间查询. #include<cstdio> #include<cstring> #include<algorithm> using namespace

HDU5692 Snacks DFS+线段树

分析:一棵以1为根的有根树,然后每个点维护从根到当前节点的路径和,当修改一个点时 只会影响的子树的和,最优值也是子树最大的值 #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; typedef long long LL; const int N=1e5+5; const LL INF=1ll*1e11; struc

Linux snacks from &lt;linux kernel development&gt;

introduction to the Linux kernel 1.operating system 1) considered the parts of the system 2) responsible for basic use and administration. 3) includes the kernel and device drivers, boot loader, command shell or other user interface, and basic file a

O - Snacks(DFS序)

百度科技园内有nn个零食机,零食机之间通过n−1n−1条路相互连通.每个零食机都有一个值vv,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值vv会时常发生变化.小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次.另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机. 为小度熊规划一个路线,使得路线上的价值总和最大. Input输入数据第一行是一个整数T(T≤10)T(T≤10),表示有TT组测试数据. 对于每组数据,包含两个整数n,m(1≤n,m