zoukankan      html  css  js  c++  java
  • P2590 [ZJOI2008]树的统计

    传送门

    题目描述

    一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。

    我们将以下面的形式来要求你对这棵树完成一些操作:

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

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

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

    注意:从点u到点v的路径上的节点包括u和v本身

    输入输出格式

    输入格式:

     

    输入文件的第一行为一个整数n,表示节点的个数。

    接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。

    接下来一行n个整数,第i个整数wi表示节点i的权值。

    接下来1行,为一个整数q,表示操作的总数。

    接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。

     

    输出格式:

     

    对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

     

    输入输出样例

    输入样例#1:
    4
    1 2
    2 3
    4 1
    4 2 1 3
    12
    QMAX 3 4
    QMAX 3 3
    QMAX 3 2
    QMAX 2 3
    QSUM 3 4
    QSUM 2 1
    CHANGE 1 5
    QMAX 3 4
    CHANGE 3 6
    QMAX 3 4
    QMAX 2 4
    QSUM 3 4
    
    输出样例#1: 
    4
    1
    2
    2
    10
    6
    5
    6
    5
    16
    

    说明

    对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。.

    用一句话来形容,这是裸的!!!!

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 const int maxn=1e5+10;
      8 struct node
      9 {
     10     int next;
     11     int from;
     12     int to;
     13 }way[maxn];
     14 int tot;
     15 int head[maxn];
     16 int size[maxn];
     17 int sumv[maxn<<2];
     18 int maxv[maxn<<2];
     19 int father[maxn];
     20 int top[maxn];
     21 int son[maxn];
     22 int a[maxn<<2];
     23 int deep[maxn];
     24 const int inf=1e9+10;
     25 int tuop[maxn];
     26 int n;
     27 int pre[maxn];
     28 int cnt=0;
     29 
     30 int add(int x,int y)
     31 {
     32     way[++tot].next=head[x];
     33     way[tot].to=y;
     34     way[tot].from=x;
     35     head[x]=tot;
     36 }
     37 
     38 void dfs1(int x,int fa)
     39 {
     40     size[x]=1;
     41     for(int i=head[x];i;i=way[i].next)
     42     {
     43         int to=way[i].to;
     44         if(to==fa)
     45         {
     46             continue;
     47         }
     48         deep[to]=deep[x]+1;
     49         father[to]=x;
     50         dfs1(to,x);
     51         size[x]+=size[to];
     52         if(size[to]>size[son[x]])
     53         {
     54             son[x]=to;
     55         }
     56     }
     57 }
     58 void dfs2(int x,int tp)
     59 {
     60     top[x]=tp;
     61     tuop[x]=++cnt;
     62     pre[cnt]=x;
     63     if(son[x])
     64     {
     65         dfs2(son[x],tp);
     66     }
     67     for(int i=head[x];i;i=way[i].next)
     68     {
     69         int to=way[i].to;
     70         if(to==father[x]||to==son[x])
     71         continue;
     72         dfs2(to,to);
     73     }
     74 }
     75 inline void pushup(int x)
     76 {
     77     sumv[x]=sumv[x<<1]+sumv[(x<<1)^1];
     78     maxv[x]=max(maxv[x<<1],maxv[(x<<1)^1]);
     79 }
     80 void build(int x,int l,int r)
     81 {
     82     if(l==r)
     83     {
     84         sumv[x]=maxv[x]=a[pre[l]];
     85         return ;
     86     }
     87     int mid=(l+r)>>1;
     88     build(x<<1,l,mid);
     89     build((x<<1)^1,mid+1,r);
     90     pushup(x);
     91 }
     92 void jia(int x,int l,int r,int q,int v)
     93 {
     94     if(l==r)
     95     {
     96         sumv[x]=maxv[x]=v;
     97         return ;
     98     }
     99     int mid=(l+r)>>1;
    100     if(q<=mid)
    101     {
    102         jia(x<<1,l,mid,q,v);
    103     }
    104     else
    105     {
    106         jia((x<<1)^1,mid+1,r,q,v);
    107     }
    108     pushup(x);
    109 }
    110 int cha(int x,int l,int r,int ls,int rs)
    111 {
    112     int ans=0;
    113     if(ls<=l&&r<=rs)
    114     {
    115         return sumv[x];
    116     }
    117     int mid=(l+r)>>1;
    118     if(ls<=mid)
    119     {
    120         ans+=cha(x<<1,l,mid,ls,rs);
    121     }
    122     if(rs>mid)
    123     {
    124         ans+=cha((x<<1)^1,mid+1,r,ls,rs);
    125     }
    126     pushup(x);
    127     return ans;
    128 }
    129 /*int chamax(int x,int l,int r,int ls,int rs)
    130 {
    131     int ans=-inf;
    132     if(ls<=l&&r<=rs)
    133     {
    134         return maxv[x];
    135     }
    136     int mid=(l+r)>>1;
    137     if(ls<=mid)
    138     {
    139         ans=max(ans,chamax(x<<1,l,mid,ls,rs));
    140     }
    141     if(rs>mid)
    142     {
    143         ans=max(ans,chamax((x<<1)^1,mid+1,r,ls,rs));
    144     }
    145     pushup(x);
    146     return ans;
    147 }*/
    148 int chamax(int o,int l,int r,int ql,int qr){
    149     int mid=(l+r)/2,ans=-inf;
    150     if (ql<=l&&r<=qr)return maxv[o];
    151     if (ql<=mid)ans=max(ans,chamax(o*2,l,mid,ql,qr));
    152     if (qr>mid)ans=max(ans,chamax(o*2+1,mid+1,r,ql,qr));
    153     pushup(o);
    154     return ans;
    155 }
    156 int qsum(int x,int to)
    157 {
    158     int ans=0;
    159     while(top[x]!=top[to])
    160     {
    161         if(deep[top[x]]<deep[top[to]])
    162         {
    163             swap(x,to);
    164         }
    165         ans+=cha(1,1,n,tuop[top[x]],tuop[x]);
    166         x=father[top[x]];
    167     }
    168     if(deep[x]<deep[to])
    169     {
    170         swap(x,to);
    171     }
    172     ans+=cha(1,1,n,tuop[to],tuop[x]);
    173     return ans;
    174 }
    175 int qmax(int x,int to)
    176 {
    177     int ans=-inf;
    178     while(top[x]!=top[to])
    179     {
    180         if(deep[top[x]]<deep[top[to]])
    181         {
    182             swap(x,to);
    183         }
    184         
    185         ans=max(ans,chamax(1,1,n,tuop[top[x]],tuop[x]));
    186         x=father[top[x]];
    187     }
    188     if(deep[x]<deep[to])
    189     {
    190         swap(x,to);
    191     }
    192     ans=max(ans,chamax(1,1,n,tuop[to],tuop[x]));
    193     return ans;
    194 }
    195 int main()
    196 {
    197     //freopen("www.out","w",stdout);
    198     memset(a,0,sizeof(a));
    199     memset(head,0,sizeof(head));
    200     scanf("%d",&n);
    201     for(int i=1;i<n;i++)
    202     {
    203         int u;
    204         int v;
    205         scanf("%d%d",&u,&v);
    206         add(u,v);
    207         add(v,u);
    208     }
    209     for(int i=1;i<=n;i++)
    210     {
    211         scanf("%d",&a[i]);
    212     }
    213     deep[1]=1;
    214     father[1]=1;
    215     dfs1(1,-1);
    216     dfs2(1,1);
    217     build(1,1,n);
    218     int T;
    219     scanf("%d",&T);
    220     while(T--)
    221     {
    222         char flag[10];
    223         int x;
    224         int y;
    225         scanf("%s%d%d",flag,&x,&y);
    226         if(flag[1]=='H')
    227         {
    228             jia(1,1,n,tuop[x],y);
    229         }
    230         else
    231         if(flag[1]=='M')
    232         {
    233             printf("%d
    ",qmax(x,y));
    234         }
    235         else
    236         if(flag[1]=='S')
    237         {
    238             printf("%d
    ",qsum(x,y));
    239         }
    240     }
    241     return 0;
    242 }

     

  • 相关阅读:
    [BZOJ4869][洛谷P3747][六省联考2017]相逢是问候(线段树)
    [WC2014][BZOJ3435][洛谷P3920]紫荆花之恋(动态点分治+treap)
    JavaScript对象JQuery In Action
    每日一条SQL LEFT JOIN
    Div border 显示不出来的原因
    HTML列表标记:dl、dt、dd
    The Effective Executive 笔记 一
    c# 解析JSON的几种办法
    使用if else 容易犯的错
    每日一句SQL:内联视图
  • 原文地址:https://www.cnblogs.com/2529102757ab/p/10902156.html
Copyright © 2011-2022 走看看