bzoj1036 [ZJOI2008]树的统计Count
一道比较好写的树剖+线段树
只是查询的内容有点多而已
直接上代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<string> 5 #include<cstring> 6 #include<cmath> 7 #include<algorithm> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 using namespace std; 13 const int inf=~0u>>1; 14 struct seg 15 { 16 int l,r; 17 long long int max,sum; 18 seg() 19 { 20 sum=0,max=-inf; 21 } 22 }t[200020]; 23 void build(const int &k,const int &l,const int &r) 24 { 25 t[k].l=l,t[k].r=r; 26 if(l==r)return ; 27 int son1=k<<1,son2=k<<1|1,mid=(l+r)>>1; 28 build(son1,l,mid); 29 build(son2,mid+1,r); 30 } 31 void update(const int &k,const int &a,const long long int &x) 32 { 33 int l=t[k].l,r=t[k].r; 34 int mid=(l+r)>>1,son1=k<<1,son2=k<<1|1; 35 if(l==r) 36 { 37 t[k].sum=t[k].max=x; 38 return ; 39 } 40 if(a<=mid)update(son1,a,x); 41 else update(son2,a,x); 42 t[k].sum=t[son1].sum+t[son2].sum; 43 t[k].max=max(t[son1].max,t[son2].max); 44 } 45 long long int qsum(const int &k,const int &l,const int &r) 46 { 47 if(l<=t[k].l&&r>=t[k].r)return t[k].sum; 48 long long int ret=0; 49 int son1=k<<1,son2=k<<1|1,mid=(t[k].l+t[k].r)>>1; 50 if(l<=mid)ret+=qsum(son1,l,r); 51 if(r>mid)ret+=qsum(son2,l,r); 52 return ret; 53 } 54 long long int qmax(const int &k,const int &l,const int &r) 55 { 56 if(l<=t[k].l&&r>=t[k].r)return t[k].max; 57 long long int ret=-inf; 58 int son1=k<<1,son2=k<<1|1,mid=(t[k].l+t[k].r)>>1; 59 if(l<=mid)ret=max(ret,qmax(son1,l,r)); 60 if(mid<r)ret=max(ret,qmax(son2,l,r)); 61 return ret; 62 } 63 int n,shen[30030],fa[30030][20],son[30030],top[30030],dfn[30030],tot; 64 long long int w[30030]; 65 int head[30030],next[60060],zhi[60060],ed; 66 int dfs(const int &x) 67 { 68 for(int i=1;i<=15;i++) 69 { 70 if(shen[x]<(1<<i))break; 71 fa[x][i]=fa[fa[x][i-1]][i-1]; 72 } 73 int ret=1,temp,Max=0; 74 for(int i=head[x];i;i=next[i]) 75 { 76 if(zhi[i]==fa[x][0])continue; 77 shen[zhi[i]]=shen[x]+1,fa[zhi[i]][0]=x; 78 temp=dfs(zhi[i]),ret+=temp; 79 if(temp>Max)Max=temp,son[x]=zhi[i]; 80 } 81 return ret; 82 } 83 void dfs2(const int &x,const int &t) 84 { 85 if(!x)return ; 86 top[x]=t,dfn[x]=++tot; 87 dfs2(son[x],t); 88 for(int i=head[x];i;i=next[i]) 89 if(zhi[i]!=fa[x][0]&&zhi[i]!=son[x])dfs2(zhi[i],zhi[i]); 90 return ; 91 } 92 int lca(int x,int y) 93 { 94 if(shen[x]<shen[y])swap(x,y); 95 int tmp=shen[x]-shen[y]; 96 for(int i=0;i<=15;i++) 97 if((1<<i)&tmp)x=fa[x][i]; 98 for(int i=15;i>=0;i--) 99 if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i]; 100 return x==y?x:fa[x][0]; 101 } 102 long long int qqsum(int x,int &LCA) 103 { 104 long long int ret=0; 105 while(top[x]!=top[LCA]) 106 { 107 ret+=qsum(1,dfn[top[x]],dfn[x]); 108 x=fa[top[x]][0]; 109 } 110 ret+=qsum(1,dfn[LCA],dfn[x]); 111 return ret; 112 } 113 long long int qqmax(int x,int &LCA) 114 { 115 long long int ret=-inf; 116 while(top[x]!=top[LCA]) 117 { 118 ret=max(ret,qmax(1,dfn[top[x]],dfn[x])); 119 x=fa[top[x]][0]; 120 } 121 ret=max(ret,qmax(1,dfn[LCA],dfn[x])); 122 return ret; 123 } 124 void add(const int &a,const int &b) 125 { 126 ed++; 127 next[ed]=head[a],head[a]=ed,zhi[ed]=b; 128 ed++; 129 next[ed]=head[b],head[b]=ed,zhi[ed]=a; 130 } 131 int main() 132 { 133 int u,v; 134 scanf("%d",&n); 135 for(int i=1;i<n;i++) 136 { 137 scanf("%d%d",&u,&v); 138 add(u,v); 139 } 140 dfs(1); 141 dfs2(1,1); 142 build(1,1,n); 143 for(int i=1;i<=n;i++) 144 { 145 scanf("%lld",&w[i]); 146 update(1,dfn[i],w[i]); 147 } 148 int q; 149 scanf("%d",&q); 150 char s[10]={""}; 151 int x,y,LCA; 152 for(int i=1;i<=q;i++) 153 { 154 scanf("%s",s); 155 scanf("%d%d",&x,&y); 156 if(s[0]=='C'&&s[1]=='H') 157 update(1,dfn[x],y),w[x]=y; 158 else if(s[0]=='Q'&&s[1]=='M') 159 { 160 LCA=lca(x,y); 161 printf("%lld\n",max(qqmax(x,LCA),qqmax(y,LCA))); 162 } 163 else if(s[1]=='S') 164 { 165 LCA=lca(x,y); 166 printf("%lld\n",qqsum(x,LCA)+qqsum(y,LCA)-w[LCA]); 167 } 168 } 169 return 0; 170 }
3.25复习,补了一发,快了不少
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 int n,m,head[30030],next[60060],zhi[60060],dfn[30030],ed; 34 int fa[30030],son[30030],top[30030],shen[30030],w[30030],tot; 35 int dfs(int x) 36 { 37 int ret=1,temp,Max=0; 38 for(int i=head[x];i;i=next[i])if(zhi[i]!=fa[x]) 39 { 40 shen[zhi[i]]=shen[x]+1,fa[zhi[i]]=x; 41 temp=dfs(zhi[i]); 42 ret+=temp; 43 if(Max<temp)Max=temp,son[x]=zhi[i]; 44 } 45 return ret; 46 } 47 void dfs(int x,int t) 48 { 49 if(!x)return ; 50 top[x]=t,dfn[x]=++tot; 51 dfs(son[x],t); 52 for(int i=head[x];i;i=next[i])if(zhi[i]!=fa[x]&&zhi[i]!=son[x]) 53 dfs(zhi[i],zhi[i]); 54 } 55 int lca(int x,int y) 56 { 57 while(top[x]!=top[y]) 58 if(shen[top[x]]>shen[top[y]])x=fa[top[x]]; 59 else y=fa[top[y]]; 60 return shen[x]<shen[y]?x:y; 61 } 62 void add(int a,int b) 63 { 64 next[++ed]=head[a],head[a]=ed,zhi[ed]=b; 65 next[++ed]=head[b],head[b]=ed,zhi[ed]=a; 66 } 67 namespace seg 68 { 69 struct tree 70 { 71 int l,r,sum,Max; 72 }t[120012]; 73 void build(int k,int l,int r) 74 { 75 t[k].l=l,t[k].r=r; 76 if(l==r){t[k].sum=t[k].Max=w[l];return ;} 77 int mid=(l+r)>>1,p1=k<<1,p2=p1|1; 78 build(p1,l,mid),build(p2,mid+1,r); 79 t[k].sum=t[p1].sum+t[p2].sum; 80 t[k].Max=max(t[p1].Max,t[p2].Max); 81 } 82 void change(int k,int wei,int x) 83 { 84 int l=t[k].l,r=t[k].r; 85 if(l==r){t[k].sum=t[k].Max=w[wei];return ;} 86 int mid=(l+r)>>1,p1=k<<1,p2=p1|1; 87 if(wei<=mid)change(p1,wei,x); 88 else change(p2,wei,x); 89 t[k].sum=t[p1].sum+t[p2].sum; 90 t[k].Max=max(t[p1].Max,t[p2].Max); 91 } 92 int querysum(int k,int l,int r) 93 { 94 if(t[k].l>=l&&t[k].r<=r)return t[k].sum; 95 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 96 if(r<=mid)return querysum(p1,l,r); 97 if(l>mid)return querysum(p2,l,r); 98 return querysum(p1,l,r)+querysum(p2,l,r); 99 } 100 int querymax(int k,int l,int r) 101 { 102 if(t[k].l>=l&&t[k].r<=r)return t[k].Max; 103 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 104 if(r<=mid)return querymax(p1,l,r); 105 if(l>mid)return querymax(p2,l,r); 106 return max(querymax(p1,l,r),querymax(p2,l,r)); 107 } 108 } 109 int querymax(int x,int y) 110 { 111 using namespace seg; 112 int z=lca(x,y),ret=-33333; 113 while(shen[top[x]]>shen[z])ret=max(ret,querymax(1,dfn[top[x]],dfn[x])),x=fa[top[x]]; 114 ret=max(ret,querymax(1,dfn[z],dfn[x])); 115 while(shen[top[y]]>shen[z])ret=max(ret,querymax(1,dfn[top[y]],dfn[y])),y=fa[top[y]]; 116 ret=max(ret,querymax(1,dfn[z],dfn[y])); 117 return ret; 118 } 119 int querysum(int x,int y) 120 { 121 using namespace seg; 122 int z=lca(x,y),ret=0; 123 while(shen[top[x]]>shen[z])ret+=querysum(1,dfn[top[x]],dfn[x]),x=fa[top[x]]; 124 ret+=querysum(1,dfn[z],dfn[x]); 125 while(shen[top[y]]>shen[z])ret+=querysum(1,dfn[top[y]],dfn[y]),y=fa[top[y]]; 126 ret+=querysum(1,dfn[z],dfn[y]); 127 return ret-w[dfn[z]]; 128 } 129 int main() 130 { 131 inin(n); 132 re(i,2,n) 133 { 134 int a,b;inin(a),inin(b); 135 add(a,b); 136 } 137 dfs(1),dfs(1,1); 138 re(i,1,n)inin(w[dfn[i]]); 139 seg::build(1,1,n); 140 inin(m); 141 re(i,1,m) 142 { 143 char s[10];int a,b; 144 strin(s);inin(a),inin(b); 145 if(s[1]=='M')printf("%d\n",querymax(a,b)); 146 else if(s[1]=='S')printf("%d\n",querysum(a,b)); 147 else w[dfn[a]]=b,seg::change(1,dfn[a],b); 148 } 149 return 0; 150 }