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

    洛谷 P2590 传送门

    bzoj 1036 传送门

    感觉最近有点虚,码个板子爽一下。

    居然没一A,交了两遍才A......

    其原因是定义qmx函数的时候我懒得重敲一遍,直接把qsum那个复制过来改了一下。

    然后忘把qsum(p<<1,l,r)和qsum(p<<1|1,l,r)改成qmx了。

    这样的话只要是qmx操作,第一遍还是qmx,分治到两边就变成qsum了......

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 
      6 int n,q;
      7 int hd[30005],to[60005],nx[60005],ec;
      8 int bv[30005];
      9 
     10 void edge(int af,int at)
     11 {
     12     to[++ec]=at;
     13     nx[ec]=hd[af];
     14     hd[af]=ec;
     15 }
     16 
     17 int f[30005],dep[30005],tp[30005];
     18 int sz[30005],son[30005];
     19 int in[30005],out[30005],pc,pos[30005];
     20 
     21 void pre(int p,int fa)
     22 {
     23     f[p]=fa;
     24     dep[p]=dep[fa]+1;
     25     sz[p]=1;
     26     for(int i=hd[p];i;i=nx[i])
     27     {
     28         if(to[i]==fa)continue;
     29         pre(to[i],p);
     30         sz[p]+=sz[to[i]];
     31         if(sz[son[p]]<sz[to[i]])son[p]=to[i];
     32     }
     33 }
     34 
     35 void dfs(int p)
     36 {
     37     in[p]=++pc;
     38     pos[pc]=p;
     39     if(p==son[f[p]])tp[p]=tp[f[p]];
     40     else tp[p]=p;
     41     if(son[p])dfs(son[p]);
     42     for(int i=hd[p];i;i=nx[i])
     43         if(to[i]!=f[p]&&to[i]!=son[p])dfs(to[i]);
     44     out[p]=pc;
     45 }
     46 
     47 int sum[120005],mx[120005],lb[120005],rb[120005];
     48 
     49 void pushup(int p)
     50 {
     51     sum[p]=sum[p<<1]+sum[p<<1|1];
     52     mx[p]=max(mx[p<<1],mx[p<<1|1]);
     53 }
     54 
     55 void build(int p,int l,int r)
     56 {
     57     lb[p]=l,rb[p]=r;
     58     if(l==r)
     59     {
     60         mx[p]=sum[p]=bv[pos[l]];
     61         return;
     62     }
     63     int mid=(l+r)>>1;
     64     build(p<<1,l,mid);
     65     build(p<<1|1,mid+1,r);
     66     pushup(p);
     67 }
     68 
     69 void change(int p,int pnt,int v)
     70 {
     71     if(lb[p]==rb[p])
     72     {
     73         sum[p]=mx[p]=v;
     74         return;
     75     }
     76     int mid=(lb[p]+rb[p])>>1;
     77     if(pnt<=mid)change(p<<1,pnt,v);
     78     else change(p<<1|1,pnt,v);
     79     pushup(p);
     80 }
     81 
     82 int qsum(int p,int l,int r)
     83 {
     84     if(lb[p]>=l&&rb[p]<=r)return sum[p];
     85     int ret=0,mid=(lb[p]+rb[p])>>1;
     86     if(l<=mid)ret+=qsum(p<<1,l,r);
     87     if(r>mid)ret+=qsum(p<<1|1,l,r);
     88     return ret;
     89 }
     90 
     91 int qmx(int p,int l,int r)
     92 {
     93     if(lb[p]>=l&&rb[p]<=r)return mx[p];
     94     int ret=-0x3f3f3f3f,mid=(lb[p]+rb[p])>>1;
     95     if(l<=mid)ret=max(qmx(p<<1,l,r),ret);
     96     if(r>mid)ret=max(qmx(p<<1|1,l,r),ret);
     97     return ret;
     98 }
     99 
    100 int main()
    101 {
    102     scanf("%d",&n);
    103     for(int i=1;i<n;i++)
    104     {
    105         int ff,tt;
    106         scanf("%d%d",&ff,&tt);
    107         edge(ff,tt);
    108         edge(tt,ff);
    109     }
    110     for(int i=1;i<=n;i++)scanf("%d",&bv[i]);
    111     pre(1,1);
    112     dfs(1);
    113     build(1,1,n);
    114     scanf("%d",&q);
    115     while(q--)
    116     {
    117         char op[15];
    118         scanf("%s",op+1);
    119         if(op[2]=='H')
    120         {
    121             int u,t;
    122             scanf("%d%d",&u,&t);
    123             change(1,in[u],t);
    124         }
    125         if(op[2]=='M')
    126         {
    127             int x,y;
    128             scanf("%d%d",&x,&y);
    129             int ans=-0x3f3f3f3f;
    130             while(tp[x]!=tp[y])
    131             {
    132                 if(dep[tp[x]]<dep[tp[y]])swap(x,y);
    133                 ans=max(qmx(1,in[tp[x]],in[x]),ans);
    134                 x=f[tp[x]];
    135             }
    136             if(dep[x]>dep[y])swap(x,y);
    137             ans=max(qmx(1,in[x],in[y]),ans);
    138             printf("%d
    ",ans);
    139         }
    140         if(op[2]=='S')
    141         {
    142             int x,y;
    143             scanf("%d%d",&x,&y);
    144             int ans=0;
    145             while(tp[x]!=tp[y])
    146             {
    147                 if(dep[tp[x]]<dep[tp[y]])swap(x,y);
    148                 ans+=qsum(1,in[tp[x]],in[x]);
    149                 x=f[tp[x]];
    150             }
    151             if(dep[x]>dep[y])swap(x,y);
    152             ans+=qsum(1,in[x],in[y]);
    153             printf("%d
    ",ans);
    154         }
    155     }
    156     return 0;
    157 }
  • 相关阅读:
    01背包问题需要找出相应路径
    单链表的正序输出和逆序输出
    二叉树之叶子节点个数
    01背包问题
    STL之map和multimap(关联容器)
    python的tips:字符和字符串的问题
    postman的使用(转载)
    python tips(3);import的机制
    python每日一类(5):itertools模块
    python每日一类(4):slice
  • 原文地址:https://www.cnblogs.com/eternhope/p/9909650.html
Copyright © 2011-2022 走看看