HYSBZ 1036(树的统计Count)

题目链接:传送门

题目大意:中文题,略

题目思路:树链剖分裸题。

闲谈:树链越练越熟练了

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <cstring>
  7 #include <stack>
  8 #include <cctype>
  9 #include <queue>
 10 #include <string>
 11 #include <vector>
 12 #include <set>
 13 #include <map>
 14 #include <climits>
 15 #define lson rt<<1,l,mid
 16 #define rson rt<<1|1,mid+1,r
 17 #define fi first
 18 #define se second
 19 #define ping(x,y) ((x-y)*(x-y))
 20 #define mst(x,y) memset(x,y,sizeof(x))
 21 #define mcp(x,y) memcpy(x,y,sizeof(y))
 22 using namespace std;
 23 #define gamma 0.5772156649015328606065120
 24 #define MOD 1000000007
 25 #define inf 0x3f3f3f3f
 26 #define N 30005
 27 #define maxn 30010
 28 typedef pair<int,int> PII;
 29 typedef long long LL;
 30 LL read(){
 31     LL x=0,f=1;char ch=getchar();
 32     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
 33     while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();}
 34     return x*f;
 35 }
 36
 37 int n,m,flag,L,R;
 38 int son[N],siz[N],top[N],id[N],tid,a[N];
 39 int dep[N],posi[N],fa[N],head[N],hcnt;
 40 struct Node{int to,nxt,v;}node[maxn<<1];
 41 struct Seg{int sum,v;}seg[N<<2];
 42 inline void init(){
 43     mst(head,-1);tid=hcnt=0;mst(siz,0);mst(son,0);mst(id,0);
 44 }
 45 void dfs1(int u,int f,int deep){
 46     dep[u]=deep,fa[u]=f,siz[u]++;
 47     for(int i=head[u];~i;i=node[i].nxt){
 48         int e=node[i].to;
 49         if(e==f)continue;
 50         dfs1(e,u,deep+1);
 51         siz[u]+=siz[e];
 52         if(!son[u]||siz[son[u]]<siz[e])
 53             son[u]=e;
 54     }
 55 }
 56 void dfs2(int u,int tp){
 57     top[u]=tp,id[u]=++tid,posi[tid]=u;
 58     if(!son[u])return;dfs2(son[u],tp);
 59     for(int i=head[u];~i;i=node[i].nxt){
 60         int e=node[i].to;
 61         if(!id[e])dfs2(e,e);
 62     }
 63 }
 64 inline void pushup(int rt){
 65     seg[rt].sum=seg[rt<<1].sum+seg[rt<<1|1].sum;
 66     seg[rt].v=max(seg[rt<<1].v,seg[rt<<1|1].v);
 67 }
 68 void build(int rt,int l,int r){
 69     if(l==r){seg[rt].v=seg[rt].sum=a[posi[l]];return;}
 70     int mid=l+r>>1;
 71     build(lson);build(rson);
 72     pushup(rt);
 73 }
 74 void update(int rt,int l,int r,int v){
 75     if(l==r){seg[rt].v=seg[rt].sum=v;return;}
 76     int mid=l+r>>1;
 77     if(L<=mid)update(lson,v);
 78     else update(rson,v);
 79     pushup(rt);
 80 }
 81 int query(int rt,int l,int r){
 82     if(L<=l&&r<=R){if(flag==0)return seg[rt].v;return seg[rt].sum;}
 83     int mid=l+r>>1;
 84     int temp;
 85     if(flag){
 86         temp=0;
 87         if(L<=mid)temp+=query(lson);
 88         if(R>mid) temp+=query(rson);
 89     }
 90     else{
 91         temp=-inf;
 92         if(L<=mid)temp=max(temp,query(lson));
 93         if(R>mid) temp=max(temp,query(rson));
 94     }
 95     return temp;
 96 }
 97 void lca(int x,int y,int fl){
 98     flag=fl;
 99     if(fl){
100         int res=0;
101         while(top[x]!=top[y]){
102             if(dep[top[x]]<dep[top[y]])swap(x,y);
103             L=id[top[x]],R=id[x];
104             res+=query(1,1,n);
105             x=fa[top[x]];
106         }
107         if(dep[x]>dep[y])swap(x,y);
108         L=id[x],R=id[y];
109         res+=query(1,1,n);
110         printf("%d\n",res);
111     }
112     else{
113         int res=-inf;
114         while(top[x]!=top[y]){
115             if(dep[top[x]]<dep[top[y]])swap(x,y);
116             L=id[top[x]],R=id[x];
117             res=max(res,query(1,1,n));
118             x=fa[top[x]];
119         }
120         if(dep[x]>dep[y])swap(x,y);
121         L=id[x],R=id[y];
122         res=max(res,query(1,1,n));
123         printf("%d\n",res);
124     }
125 }
126 int main(){
127     int i,j,group,x,y,v;
128     while(scanf("%d",&n)!=EOF){
129         init();
130         for(i=1;i<n;++i){
131             x=read(),y=read();
132             node[hcnt].to=y,node[hcnt].nxt=head[x],head[x]=hcnt++;
133             node[hcnt].to=x,node[hcnt].nxt=head[y],head[y]=hcnt++;
134         }
135         for(i=1;i<=n;++i)a[i]=read();
136         dfs1(1,1,1);dfs2(1,1);build(1,1,n);
137         m=read();
138         char str[111];
139         while(m--){
140             scanf("%s",str);x=read(),y=read();
141             if(strcmp(str,"QMAX")==0) lca(x,y,0);
142             else if(strcmp(str,"QSUM")==0) lca(x,y,1);
143             else L=id[x],update(1,1,n,y);
144         }
145     }
146     return 0;
147 }
时间: 2024-10-27 18:18:11

HYSBZ 1036(树的统计Count)的相关文章

HYSBZ 1036 树的统计Count(树链剖分)

HYSBZ 1036 树的统计Count 题目链接 就树链剖分,线段树维护sum和maxx即可 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 30005; int dep[N], fa[N], son[N], sz[N], top[N], id[N], idx, val[N];

HYSBZ - 1036 树的统计Count 树链剖分 求和+最大值

好水0.0 #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<set> #include<map> #include<queue> #include<vector> #include<string> #define eps 1e-12 #de

HYSBZ 1036 树的统计Count 树链剖分 线段树

傻缺模板题,练手速和正确率用.. #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <set> #include <bitset> #include <queue> #include <stack> #include <string> #include <iostream>

bzoj 1036 树的统计Count (树链剖分+线段树)

题目大意:给你一棵树,每个点都有点权 有3种操作,修改某节点的权值,求树链上节点的权值的最大值,求树链上节点的权值和 树剖裸题,搜一个树链剖分序,用线段树维护一下即可,总时间 1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <queue> 5 #define inf 0x3f3f3f3f 6 #define ll long long 7 #define N

BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)

1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14982  Solved: 6081[Submit][Status][Discuss] Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I

BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]

1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14302  Solved: 5779[Submit][Status][Discuss] Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I

BZOJ 题目1036: [ZJOI2008]树的统计Count(Link Cut Tree,修改点权求两个最大值和最大值)

1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 8421  Solved: 3439 [Submit][Status][Discuss] Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值

1036: [ZJOI2008]树的统计Count

1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 7496  Solved: 3078[Submit][Status][Discuss] Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 II

BZOJ 1036: [ZJOI2008]树的统计Count

1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 14354  Solved: 5802 [Submit][Status][Discuss] Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权

bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 10677  Solved: 4313[Submit][Status][Discuss] Description 一 棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值