• 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
    ",max(qqmax(x,LCA),qqmax(y,LCA)));
    162         }
    163         else if(s[1]=='S')
    164         {
    165             LCA=lca(x,y);
    166             printf("%lld
    ",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
    ",querymax(a,b));
    146         else if(s[1]=='S')printf("%d
    ",querysum(a,b));
    147         else w[dfn[a]]=b,seg::change(1,dfn[a],b);
    148     }
    149     return 0;
    150 }
  • 相关阅读:
    aop
    javascript学习笔记
    Hibernate一对多关联映射的配置及其级联删除问题
    Hibernate一对多单向关联和双向关联映射方法及其优缺点 (待续)
    剑指offer---08---动态规划:跳台阶
    剑指offer---07---动态规划:斐波那契数列
    剑指offer---06---数组,二分法---旋转数组的最小数字
    剑指offer---05---用栈实现队列
    剑指offer---03---从尾到头打印链表---链表
    剑指offer---04-树--重建二叉树(前序和中序)
  • 原文地址:https://www.cnblogs.com/HugeGun/p/5151024.html
Copyright © 2020-2023  润新知