zoukankan      html  css  js  c++  java
  • 1036: [ZJOI2008]树的统计Count

    树链剖分 模板题:

       和线段树一起写各种bug:

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<math.h>
      4 #include<vector>
      5 #include<string.h>
      6 #include<string>
      7 #include<set>
      8 #include<iostream>
      9 using namespace std;
     10 typedef long long ll;
     11 #define N 33333
     12 
     13 int head[N],top[N],fa[N],tot;
     14 
     15 int son[N],p[N],fp[N],dep[N],pos;
     16 int sz[N];
     17 
     18 void init()
     19 {
     20     tot=0;
     21     memset(head,-1,sizeof(head));
     22     memset(son,-1,sizeof(son));
     23     pos=0;
     24 }
     25 
     26 struct node
     27 {
     28     int v,next;
     29 }e[N<<1];
     30 
     31 void add(int u,int v)
     32 {
     33     e[tot].v=v;
     34     e[tot].next=head[u];
     35     head[u]=tot++;
     36 }
     37 
     38 void dfs(int u,int f,int d)
     39 {
     40     dep[u]=d;
     41     fa[u]=f;
     42     sz[u]=1;
     43 
     44     for (int i=head[u];i!=-1;i=e[i].next)
     45     {
     46         int v=e[i].v;
     47         if (v==f) continue;
     48         dfs(v,u,d+1);
     49         sz[u]+=sz[v];
     50         if (son[u]==1||sz[son[u]]<sz[v]) son[u]=v;
     51     }
     52 }
     53 
     54 void getpos(int u,int sp)
     55 {
     56     top[u]=sp;
     57     p[u]=++pos;
     58     fp[pos]=u;
     59     if (son[u]==-1) return;
     60     getpos(son[u],sp);
     61     for (int i=head[u];i!=-1;i=e[i].next)
     62     {
     63        int v=e[i].v;
     64        if (v!=son[u]&&v!=fa[u])
     65        getpos(v,v);
     66     }
     67 }
     68 
     69 struct node2
     70 {
     71     int l,r,Max,sum;
     72 }tree[N<<2];
     73 
     74 
     75 void pushup(int rt)
     76 {
     77     tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max);
     78     tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
     79 }
     80 
     81 
     82 void build(int l,int r,int rt)
     83 {
     84     tree[rt].l=l;
     85     tree[rt].r=r;
     86     tree[rt].Max=tree[rt].sum=0;
     87 
     88     if (l==r) return ;
     89     int m=(l+r)>>1;
     90     build(l,m,rt<<1);
     91     build(m+1,r,rt<<1|1);
     92 }
     93 
     94 void update(int pos,int x,int l,int r,int rt)
     95 {
     96     if (l==r)
     97     {
     98         tree[rt].Max=tree[rt].sum=x;
     99         return;
    100     }
    101     int m=(l+r)>>1;
    102     if (pos<=m) update(pos,x,l,m,rt<<1);
    103     else update(pos,x,m+1,r,rt<<1|1);
    104     pushup(rt);
    105 }
    106 
    107 int  querymax(int l,int r,int rt)
    108 {
    109   if (tree[rt].l>=l&&tree[rt].r<=r)
    110       return tree[rt].Max;
    111   int m=(tree[rt].l+tree[rt].r)>>1;
    112 
    113   if (r<=m) return querymax(l,r,rt<<1);
    114   else if (l>m) return querymax(l,r,rt<<1|1);
    115   else return max(querymax(l,m,rt<<1),querymax(m+1,r,rt<<1|1));
    116 }
    117 
    118 
    119 int  querysum(int l,int r,int rt)
    120 {
    121   if (tree[rt].l>=l&&tree[rt].r<=r)
    122       return tree[rt].sum;
    123 
    124   int m=(tree[rt].l+tree[rt].r)>>1;
    125   if (r<=m) return querysum(l,r,rt<<1);
    126   else if (l>m) return querysum(l,r,rt<<1|1);
    127   else return querysum(l,m,rt<<1)+querysum(m+1,r,rt<<1|1);
    128 }
    129 
    130 int Sum,Max;
    131 
    132 void  lca(int u,int v)
    133 {
    134     int fu=top[u];
    135     int fv=top[v];
    136     Sum=0;
    137     Max=-24242554;
    138     while (fu!=fv)
    139     {
    140         if (dep[fu]<dep[fv])
    141         {
    142             swap(fu,fv);
    143             swap(u,v);
    144         }
    145 
    146         Max=max(Max,querymax(p[fu],p[u],1));
    147         Sum+=querysum(p[fu],p[u],1);
    148         u=fa[fu];
    149         fu=top[u];
    150     }
    151     
    152     if (dep[u]>dep[v]) swap(u,v);
    153     Max=max(Max,querymax(p[u],p[v],1));
    154     Sum+=querysum(p[u],p[v],1);
    155     
    156     //Max=max(Max,querymax(p[fa[u]],p[v],1));
    157     //Sum+=querysum(p[fa[u]],p[v],1);
    158 }
    159 int a[N];
    160 
    161 int main()
    162 {
    163     int n;
    164     scanf("%d",&n);
    165     init();
    166     for (int i=1;i<n;i++)
    167     {
    168         int x,y;
    169         scanf("%d%d",&x,&y);
    170         add(x,y);
    171         add(y,x);
    172     }
    173     dfs(1,0,0);
    174     getpos(1,1);
    175     build(1,pos,1);
    176 
    177     for (int i=1;i<=n;i++) scanf("%d",&a[i]),update(p[i],a[i],1,pos,1);
    178 
    179     int Q;
    180     scanf("%d",&Q);
    181     while (Q--)
    182     {
    183       char s[10];
    184       int x,y;
    185       scanf("%s",s);
    186       scanf("%d%d",&x,&y);
    187       if (s[0]=='C') update(p[x],y,1,pos,1);
    188       else
    189       {
    190           lca(x,y);
    191           if (s[1]=='M') printf("%d
    ",Max);
    192           else printf("%d
    ",Sum);
    193       }
    194     }
    195 
    196     return 0;
    197 }
  • 相关阅读:
    协议
    网页制作
    知识点--------二维数组
    方法---------拖延,清屏,前景色,背景色
    小知识点------遍历数组、switch case、do while
    知识点-----------函数
    循环经典--------冒泡排序,查找。
    知识点-------一维数组
    循环语句-----经典案例
    知识点--循环语句
  • 原文地址:https://www.cnblogs.com/forgot93/p/4619621.html
Copyright © 2011-2022 走看看