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

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 }

 

posted @ 2016-01-22 13:58  HugeGun  阅读(176)  评论(0编辑  收藏  举报