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 }
  • 相关阅读:
    leetcode 268. Missing Number
    DBSCAN
    python二维数组初始化
    leetcode 661. Image Smoother
    leetcode 599. Minimum Index Sum of Two Lists
    Python中的sort() key含义
    leetcode 447. Number of Boomerangs
    leetcode 697. Degree of an Array
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(1月3日)
    北京Uber优步司机奖励政策(1月2日)
  • 原文地址:https://www.cnblogs.com/cervusy/p/9909650.html
Copyright © 2011-2022 走看看