zoukankan      html  css  js  c++  java
  • 【bzoj1036】[ZJOI2008]树的统计Count

    题意:

    I. CHANGE u t : 把结点u的权值改为t

    II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值

    III. QSUM u v: 询问从点u到点v的路径上的节点的权值和

    树链剖分

    siz[v]表示以v为根的子树的节点数

    top[v]表示v所在的重链的顶端节点

    fa[v]表示v的父亲

    son[v]表示与v在同一重链上的v的儿子节点

    pos[v]表示v与其父亲节点的连边在线段树中的位置

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 using namespace std;
      8  
      9 typedef long long LL;
     10  
     11 #define INF 0x7fffffff
     12 #define N 30010
     13  
     14 struct Node
     15 {
     16     LL maxn,sum;
     17 }tr[N<<2];
     18  
     19 struct edge
     20 {
     21     int to,next;
     22 }e[N<<2];
     23  
     24 int cnt,head[N<<2];
     25  
     26 int id,siz[N],top[N],fa[N],son[N];
     27 int d[N],pos[N],v[N];
     28  
     29 char s[15];
     30  
     31 int n,m;
     32 int a,b;
     33  
     34 LL ans,sum;
     35  
     36 void link(int x,int y)
     37 {
     38     e[++cnt]=(edge){y,head[x]};
     39     head[x]=cnt;
     40 }
     41  
     42 void dfs(int x,int y)
     43 {
     44     siz[x]=1;
     45     fa[x]=y;
     46     d[x]=d[y]+1;
     47     int k=0;
     48     for (int i=head[x];i;i=e[i].next)
     49         if (e[i].to!=fa[x])
     50         {
     51             dfs(e[i].to,x);
     52             siz[x]+=siz[e[i].to];
     53             if (siz[e[i].to]>k)
     54                 k=siz[e[i].to],son[x]=e[i].to;
     55         }
     56 }
     57  
     58 void dfs2(int x,int y)
     59 {
     60     top[x]=y;
     61     pos[x]=++id;
     62     if (!son[x])
     63         return ;
     64     dfs2(son[x],y);
     65     for (int i=head[x];i;i=e[i].next)
     66         if (e[i].to!=fa[x] && e[i].to!=son[x])
     67             dfs2(e[i].to,e[i].to);
     68 }
     69  
     70 void pushup(int now)
     71 {
     72     tr[now].sum=tr[now<<1].sum+tr[now<<1|1].sum;
     73     tr[now].maxn=max(tr[now<<1].maxn,tr[now<<1|1].maxn);
     74 }
     75  
     76 void update(int nowl,int nowr,int now,int x,int y)
     77 {
     78     if (nowl==nowr)
     79     {
     80         tr[now].sum=y;
     81         tr[now].maxn=y;
     82         return ;
     83     }
     84     int mid=(nowl+nowr)>>1;
     85     if (x<=mid)
     86         update(nowl,mid,now<<1,x,y);
     87     else
     88         update(mid+1,nowr,now<<1|1,x,y);
     89     pushup(now);
     90 }
     91  
     92 void query(int nowl,int nowr,int now,int x,int y)
     93 {
     94     if (nowl==x && nowr==y)
     95     {
     96         ans=max(ans,tr[now].maxn);
     97         sum+=tr[now].sum;
     98         return ; 
     99     }
    100     int mid=(nowl+nowr)>>1;
    101     if (y<=mid)
    102         query(nowl,mid,now<<1,x,y);
    103     else if (x>mid)
    104         query(mid+1,nowr,now<<1|1,x,y);
    105     else
    106         query(nowl,mid,now<<1,x,mid),query(mid+1,nowr,now<<1|1,mid+1,y);
    107 }
    108  
    109 void find(int x,int y)
    110 {
    111     int f1=top[x],f2=top[y];
    112     ans=-INF;
    113     sum=0;
    114     while (f1!=f2)
    115     {
    116         if (d[f1]<d[f2])
    117             swap(f1,f2),swap(x,y);
    118         query(1,n,1,pos[f1],pos[x]);
    119         x=fa[f1];
    120         f1=top[x];
    121     }
    122     if (d[x]>d[y])
    123         swap(x,y);
    124     query(1,n,1,pos[x],pos[y]);
    125 }
    126  
    127 int main()
    128 {
    129     scanf("%d",&n);
    130     for (int i=1;i<n;i++)
    131     {
    132         scanf("%d%d",&a,&b);
    133         link(a,b);
    134         link(b,a);
    135     }
    136     for (int i=1;i<=n;i++)
    137         scanf("%d",&v[i]);
    138     d[1]=1;
    139     dfs(1,0);
    140     dfs2(1,1);
    141     for (int i=1;i<=n;i++)
    142         update(1,n,1,pos[i],v[i]);
    143     scanf("%d",&m);
    144     int x,y;
    145     while (m--)
    146     {
    147         scanf("%s%d%d",s,&x,&y);
    148         if (s[0]=='C')
    149             update(1,n,1,pos[x],y);
    150         else
    151         {
    152             find(x,y);
    153             if (s[1]=='M')
    154                 printf("%lld
    ",ans);
    155             else
    156                 printf("%lld
    ",sum);
    157         }
    158     }
    159     return 0;
    160 }
    161  
  • 相关阅读:
    ARM学习笔记10——GNU ARM命令行工具
    ARM学习笔记9——ARM汇编汇编语言中的伪指令
    ARM学习笔记8——通用寄存器和存储器内容交换指令和软中断指令
    ARM学习笔记7——乘法指令
    ARM学习笔记6——程序状态寄存器访问指令
    ARM学习笔记5——程序状态寄存器
    ARM学习笔记4——加载存储指令
    ARM学习笔记3——数据处理指令
    ARM学习笔记2——分支跳转指令
    ARM学习笔记1——Arm寄存器与模式的关系
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5329116.html
Copyright © 2011-2022 走看看