• [ZJOI2008]树的统计


       树剖+线段树

       据说是入门题,然而蒟蒻没有做过。

      1 #include<bits/stdc++.h>
      2 #define re register int
      3 #define maxn 100000+5
      4 #define inf 1000000000
      5 #define lson now<<1
      6 #define rson now<<1|1
      7 using namespace std;
      8 inline int read()
      9 {
     10     int x=0,f=1; 
     11     char ch=getchar();
     12     while(!isdigit(ch))
     13    {
     14        if(ch=='-') f=-1;
     15     ch=getchar();
     16 }
     17     while(isdigit(ch))
     18     {
     19         x=x*10+ch-'0';
     20         ch=getchar();
     21     }
     22     return x*f;
     23 }
     24 inline void write(int x)
     25 {
     26     if(x<0) putchar('-'),x=-x;
     27     if(x>9) write(x/10);
     28     putchar(x%10+'0');
     29 }
     30 int dep[maxn],siz[maxn],son[maxn],fa[maxn];
     31 int id[maxn],rnk[maxn],top[maxn],val[maxn];
     32 int n;
     33 struct edge{
     34     int nex,to; 
     35 }ed[maxn<<1];
     36 int head[maxn];
     37 struct tree{
     38     int sum,maxw; 
     39 }tr[maxn<<2];
     40 void pushup(int now)
     41 {
     42     tr[now].sum=tr[lson].sum+tr[rson].sum;
     43     tr[now].maxw=max(tr[lson].maxw,tr[rson].maxw);
     44 }
     45 void build(int now,int l,int r)
     46 {
     47     if(l==r)
     48     {
     49         tr[now].sum=tr[now].maxw=val[rnk[l]];
     50         return;
     51     }
     52     int mid=(l+r)>>1; 
     53     build(lson,l,mid);
     54     build(rson,mid+1,r);
     55     pushup(now); 
     56 }
     57 int qsum(int ql,int qr,int l,int r,int now)
     58 {
     59     if(l>=ql&&r<=qr) return tr[now].sum;
     60     int mid=(l+r)>>1,res=0;
     61     if(ql<=mid)  res+=qsum(ql,qr,l,mid,lson);
     62     if(qr>mid)  res+=qsum(ql,qr,mid+1,r,rson);
     63     return res;
     64 }
     65 int qmax(int ql,int qr,int l,int r,int now)
     66 {
     67     if(l>=ql&&r<=qr) return tr[now].maxw;
     68     int mid=(l+r)>>1;
     69     int Max=-inf;
     70     if(ql<=mid) Max=max(Max,qmax(ql,qr,l,mid,lson));
     71     if(qr>mid) Max=max(Max,qmax(ql,qr,mid+1,r,rson)); 
     72     return Max;
     73 }
     74 void update(int l,int r,int now,int ch,int w)
     75 {
     76     if(l==r)
     77     {
     78     tr[now].sum=tr[now].maxw=w;
     79     return;
     80     }
     81     int mid=(l+r)>>1;
     82     if(ch<=mid)
     83     update(l,mid,lson,ch,w);
     84     else 
     85     update(mid+1,r,rson,ch,w);
     86     pushup(now);
     87 }
     88 int cnt,num,q;
     89 void add(int x,int y)
     90 {
     91     ed[++cnt].nex=head[x];
     92     ed[cnt].to=y;
     93     head[x]=cnt;
     94 }
     95 void dfs(int pos,int f)
     96 {
     97     fa[pos]=f;
     98     dep[pos]=dep[f]+1;
     99     siz[pos]=1;
    100     for(re i=head[pos];i;i=ed[i].nex) 
    101     {
    102         if(ed[i].to!=f){
    103             dfs(ed[i].to,pos);
    104             siz[pos]+=siz[ed[i].to];
    105             if(siz[ed[i].to]>siz[son[pos]]) 
    106             son[pos]=ed[i].to;
    107         }
    108     }
    109 }
    110 void dfs2(int pos,int tp)
    111 {
    112     top[pos]=tp;
    113     id[pos]=++num;
    114     rnk[num]=pos;
    115     if(son[pos]) dfs2(son[pos],tp);
    116     for(re i=head[pos];i;i=ed[i].nex)
    117         if(ed[i].to!=fa[pos]&&ed[i].to!=son[pos])
    118         dfs2(ed[i].to,ed[i].to);
    119 }
    120 int qqsum(int x,int y)
    121 {
    122     int res=0;
    123     while(top[x]!=top[y]){
    124     if(dep[top[x]]<dep[top[y]]) swap(x,y);
    125     res+=qsum(id[top[x]],id[x],1,n,1);
    126     x=fa[top[x]]; 
    127 }
    128      if(dep[x]>dep[y]) swap(x,y);
    129      res+=qsum(id[x],id[y],1,n,1);
    130      return res;
    131 }
    132 int qqmax(int x,int y)
    133 {
    134     int Max=-inf;
    135     while(top[x]!=top[y]){
    136     if(dep[top[x]]<dep[top[y]]) swap(x,y);
    137     Max=max(Max,qmax(id[top[x]],id[x],1,n,1));
    138     x=fa[top[x]]; 
    139 }
    140      if(dep[x]>dep[y]) swap(x,y);
    141      Max=max(Max,qmax(id[x],id[y],1,n,1));
    142      return Max;
    143 }
    144 int main()
    145 {
    146     n=read();
    147     for(re i=1;i<=n-1;i++)
    148     {
    149         int x,y;
    150         x=read();
    151         y=read();
    152         add(x,y);
    153         add(y,x);
    154     }
    155     for(re i=1;i<=n;i++)
    156     val[i]=read();
    157     dfs(1,0);
    158     dfs2(1,1);
    159     build(1,1,n);
    160     q=read();
    161     char s[10];
    162     while(q--)
    163     {
    164         int x,y;
    165         cin>>s;
    166         x=read();
    167         y=read();
    168         if(s[0]=='C') update(1,n,1,id[x],y);
    169         else if(s[1]=='M')
    170         {
    171             write(qqmax(x,y));
    172             putchar('
    ');
    173         }
    174         else{
    175             write(qqsum(x,y));
    176             putchar('
    ');
    177         }
    178     }
    179     return 0;
    180 }
    树的统计
  • 相关阅读:
    bzoj 3308 九月的咖啡店
    8.13模拟赛
    8.10模拟赛
    8.9模拟赛
    8.8模拟赛
    Codeforces Round #406 (Div. 2) D. Legacy (线段树建图dij)
    BZOJ 2957: 楼房重建 (分块)
    SPOJ BGSHOOT
    Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)
    Lightoj-1356 Prime Independence(质因子分解)(Hopcroft-Karp优化的最大匹配)
  • 原文地址:https://www.cnblogs.com/3200Pheathon/p/11402309.html
Copyright © 2020-2023  润新知