zoukankan      html  css  js  c++  java
  • LOJ10138

    ZJOI 2008 树上的统计

    一树上有 n 个节点,编号分别为 1 到 n,每个节点都有一个权值 w。我们将以下面的形式来要求你对这棵树完成一些操作:

    1. CHANGE u t :把节点 u 权值改为t;
    2. QMAX u v :询问点 u 到点 v 路径上的节点的最大权值;
    3. QSUM u v :询问点 u 到点 v 路径上的节点的权值和。

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

    输入格式

    第一行为一个数 n,表示节点个数;

    接下来 n-1 行,每行两个整数 a,b,表示节点 a与节点 b 之间有一条边相连;

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

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

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

    输出格式

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

    样例

    样例输入

    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

    样例输出

    4
    1
    2
    2
    10
    6
    5
    6
    5
    16

    数据范围与提示

    对于 100% 的数据,有1n3×10^4,0q2×10^5。中途操作中保证每个节点的权值 w 在 30000 至 30000 之间。

    _______________________________________________________________________________________

    很简单的树剖,好久没有写了,第一次写的不知道哪里错了,还是写了第二次!

    _______________________________________________________________________________________

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 const ll maxn=30020;
      5 ll n,m;
      6 struct edge
      7 {
      8     ll u,v,nxt;
      9 }e[maxn<<1];
     10 ll head[maxn],js;
     11 void addage(ll u,ll v)
     12 {
     13     e[++js].u=u;e[js].v=v;
     14     e[js].nxt=head[u];head[u]=js;
     15 }
     16 ll w[maxn];
     17 ll dep[maxn],fat[maxn],siz[maxn],son[maxn];
     18 void dfs(ll u,ll fa)
     19 {
     20     dep[u]=dep[fa]+1;
     21     fat[u]=fa;
     22     siz[u]=1;
     23     for(ll i=head[u];i;i=e[i].nxt)
     24     {
     25         ll v=e[i].v;
     26         if(v==fa)continue;
     27         dfs(v,u);
     28         siz[u]+=siz[v];
     29         if(!son[u] || siz[son[u]]<siz[v])son[u]=v;
     30     }
     31 }
     32 ll pos[maxn],top[maxn],fos[maxn],p;
     33 void getpos(ll u,ll fa)
     34 {
     35     top[u]=fa;
     36     pos[u]=++p;
     37     fos[p]=u;
     38     if(!son[u])return ;
     39     getpos(son[u],fa);
     40     for(ll i=head[u];i;i=e[i].nxt)
     41     {
     42         ll v=e[i].v;
     43         if(v!=son[u] && v!=fat[u])getpos(v,v);
     44     }
     45 }
     46 ll MAX,SUM;
     47 ll _sum[maxn<<2],_max[maxn<<2];
     48 void update(ll cur)
     49 {
     50     _sum[cur]=_sum[cur<<1]+_sum[cur<<1|1];
     51     _max[cur]=max(_max[cur<<1],_max[cur<<1|1]);
     52 }
     53 void build(ll cur,ll l,ll r)
     54 {
     55     if(l==r)
     56     {
     57         _sum[cur]=_max[cur]=w[fos[l]];
     58         return ;
     59     }
     60     ll mid=(l+r)>>1;
     61     build(cur<<1,l,mid);
     62     build(cur<<1|1,mid+1,r);
     63     update(cur);
     64 }
     65 void query(ll cur,ll l,ll r,ll ql,ll qr)
     66 {
     67     if(ql<=l && r<=qr)
     68     {
     69         MAX=max(_max[cur],MAX);
     70         SUM+=_sum[cur];
     71         return ;
     72     }
     73     ll mid=(l+r)>>1;
     74     if(ql<=mid)query(cur<<1,l,mid,ql,qr);
     75     if(qr>mid)query(cur<<1|1,mid+1,r,ql,qr);
     76 }
     77 void ask(ll u,ll v)
     78 {
     79     ll tpu=top[u],tpv=top[v];
     80     while(tpu!=tpv)
     81     {
     82         if(dep[tpu]<dep[tpv])
     83         {
     84             swap(u,v);swap(tpu,tpv);
     85         }
     86         query(1,1,n,pos[tpu],pos[u]);
     87         u=fat[tpu];tpu=top[u];
     88     }
     89     if(dep[u]>dep[v])swap(u,v);
     90     query(1,1,n,pos[u],pos[v]);
     91 }
     92 void change(ll cur,ll l,ll r,ll p,ll x)
     93 {
     94     if(l==r)
     95     {
     96         _max[cur]=_sum[cur]=x;
     97         return ;
     98     }
     99     ll mid=(l+r)>>1;
    100     if(p<=mid)change(cur<<1,l,mid,p,x);
    101     else change(cur<<1|1,mid+1,r,p,x);
    102     update(cur);
    103 }
    104 int main()
    105 {
    106     scanf("%lld",&n);
    107     for(ll i=1,u,v;i<n;++i)
    108     {
    109         scanf("%lld%lld",&u,&v);
    110         addage(u,v);addage(v,u);
    111     }
    112     for(int i=1;i<=n;++i)scanf("%lld",w+i);
    113     scanf("%lld",&m);
    114     dfs(1,0);
    115     getpos(1,1);
    116     build(1,1,n);
    117     char s[10];
    118     ll u,v;
    119     while(m--)
    120     {
    121         scanf("%s%lld%lld",s,&u,&v);
    122         if(s[1]=='H')change(1,1,n,pos[u],v);
    123         else
    124         {
    125             MAX=-0x7fffffff,SUM=0;
    126             ask(u,v);
    127             printf("%lld
    ",s[1]=='M'?MAX:SUM);
    128         }
    129     }
    130     return 0;
    131 }
    View Code
  • 相关阅读:
    python json 和 pickle的补充 hashlib configparser logging
    go 流程语句 if goto for swich
    go array slice map make new操作
    go 基础
    块级元素 行内元素 空元素
    咽炎就医用药(慢性肥厚性咽炎)
    春季感冒是风寒还是风热(转的文章)
    秋季感冒 咳嗽 怎么选药
    解决IE浏览器“无法显示此网页”的问题
    常用的 css 样式 记录
  • 原文地址:https://www.cnblogs.com/gryzy/p/10450106.html
Copyright © 2011-2022 走看看