HYSBZ 1036(树的统计Count)
Posted Kurokey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于HYSBZ 1036(树的统计Count)的主要内容,如果未能解决你的问题,请参考以下文章
bzoj1036 [ZJOI2008]树的统计Count——LCT
bzoj 1036: [ZJOI2008]树的统计Count (树链剖分)
BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)