zoukankan      html  css  js  c++  java
  • bzoj 1036 树的统计Count (树链剖分+线段树)

    题目大意:给你一棵树,每个点都有点权

    有3种操作,修改某节点的权值,求树链上节点的权值的最大值,求树链上节点的权值和

    树剖裸题,搜一个树链剖分序,用线段树维护一下即可,总时间O(qlog^2n)

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <queue>
      5 #define inf 0x3f3f3f3f
      6 #define ll long long 
      7 #define N 30100
      8 using namespace std;
      9 
     10 char str[10];
     11 int n,num,cte;
     12 ll a[N],sum[N<<2],ma[N<<2];
     13 int dep[N],head[N],son[N],sz[N],que[N],pos[N],tp[N],fa[N];
     14 struct Chain{
     15     int up,dw;
     16     Chain(int up,int dw):up(up),dw(dw){}
     17 };
     18 struct EDGE{
     19     int to,nxt;
     20 }edge[N<<1];
     21 void edge_add(int u,int v)
     22 {
     23     cte++;
     24     edge[cte].to = v;
     25     edge[cte].nxt=head[u];
     26     head[u]=cte;
     27 }
     28 void dfs1(int x,int pre)
     29 {
     30     for(int j=head[x];j!=-1;j=edge[j].nxt)
     31     {
     32         int v=edge[j].to;
     33         if(v==pre) continue;
     34         dep[v]=dep[x]+1;
     35         fa[v]=x;
     36         dfs1(v,x);
     37         son[x]=(sz[v]>sz[son[x]])?v:son[x];
     38         sz[x]+=sz[v];
     39     }
     40     sz[x]++;
     41 }
     42 void dfs2(int x)
     43 {
     44     que[++num]=x,pos[x]=num;
     45     if(son[x]) tp[son[x]]=tp[x],dfs2(son[x]);
     46     for(int j=head[x];j!=-1;j=edge[j].nxt)
     47     {
     48         int v=edge[j].to;
     49         if(v==fa[x]||v==son[x]) continue;
     50         tp[v]=v,dfs2(v);
     51     }
     52 }
     53 void pushup(int rt){
     54     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
     55     ma[rt]=max(ma[rt<<1],ma[rt<<1|1]);
     56 }
     57 void build(int l,int r,int rt)
     58 {
     59     if(l==r){sum[rt]=ma[rt]=a[que[l]];return;}
     60     int mid=(l+r)>>1;
     61     build(l,mid,rt<<1);
     62     build(mid+1,r,rt<<1|1);
     63     pushup(rt);
     64 }
     65 void update(int x,int l,int r,int rt,ll w)
     66 {
     67     if(l==r){sum[rt]=ma[rt]=a[que[l]];return;}
     68     int mid=(l+r)>>1;
     69     if(x<=mid) update(x,l,mid,rt<<1,w);
     70     else  update(x,mid+1,r,rt<<1|1,w);
     71     pushup(rt);
     72 }
     73 ll qmax1(int L,int R,int l,int r,int rt)
     74 {
     75     if(L<=l&&r<=R) return ma[rt];
     76     int mid=(l+r)>>1;ll ans=-inf;
     77     if(L<=mid) ans=max(ans,qmax1(L,R,l,mid,rt<<1));
     78     if(R>mid) ans=max(ans,qmax1(L,R,mid+1,r,rt<<1|1));
     79     return ans;
     80 }
     81 ll qsum1(int L,int R,int l,int r,int rt)
     82 {
     83     if(L<=l&&r<=R) return sum[rt];
     84     int mid=(l+r)>>1;ll ans=0;
     85     if(L<=mid) ans+=qsum1(L,R,l,mid,rt<<1);
     86     if(R>mid) ans+=qsum1(L,R,mid+1,r,rt<<1|1);
     87     return ans;
     88 }
     89 int LCA(int x,int y)
     90 {
     91     while(tp[x]!=tp[y]){
     92         if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
     93         x=fa[tp[x]];
     94     }return dep[x]<dep[y]?x:y;
     95 }
     96 queue<Chain>q;
     97 ll Qmax(int x,int y)
     98 {
     99     while(tp[x]!=tp[y]){
    100         if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
    101         q.push(Chain(tp[x],x));
    102         x=fa[tp[x]];    
    103     } if(dep[x]<dep[y]) swap(x,y);
    104     q.push(Chain(y,x));ll ans=-inf;
    105     while(!q.empty()){
    106         Chain k=q.front();q.pop();
    107         ans=max(ans,qmax1(pos[k.up],pos[k.dw],1,n,1));
    108     }return ans;
    109 }
    110 ll Qsum(int x,int y)
    111 {
    112     while(tp[x]!=tp[y]){
    113         if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
    114         q.push(Chain(tp[x],x));
    115         x=fa[tp[x]];
    116     } if(dep[x]<dep[y]) swap(x,y);
    117     q.push(Chain(y,x));ll ans=0;
    118     while(!q.empty()){
    119         Chain k=q.front();q.pop();
    120         ans+=qsum1(pos[k.up],pos[k.dw],1,n,1);
    121     }return ans;
    122 }
    123 
    124 int main()
    125 {
    126     //freopen("data.in","r",stdin);
    127     scanf("%d",&n);
    128     int x,y;ll z;
    129     memset(head,-1,sizeof(head));
    130     for(int i=1;i<n;i++)
    131     {
    132         scanf("%d%d",&x,&y);
    133         edge_add(x,y);
    134         edge_add(y,x);
    135     } 
    136     for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    137     dep[1]=1,dfs1(1,-1);
    138     tp[1]=1,dfs2(1);
    139     build(1,n,1);
    140     int q=0;
    141     scanf("%d",&q);
    142     for(int i=1;i<=q;i++)
    143     {
    144         scanf("%s",str);
    145         if(str[1]=='H'){
    146             scanf("%d%lld",&x,&z),a[x]=z;
    147             update(pos[x],1,n,1,z);
    148         }else if(str[1]=='M'){
    149             scanf("%d%d",&x,&y);
    150             printf("%lld
    ",Qmax(x,y));
    151         }else{
    152             scanf("%d%d",&x,&y);
    153             printf("%lld
    ",Qsum(x,y));
    154         }
    155     }
    156     return 0;
    157 }
  • 相关阅读:
    计算机的几种命令行
    oracle体系结构
    数字档案馆建设指南及档案业务系统归档接口规范
    ERP系统归档
    oracle ITL(事务槽)的理解
    oracle表属性
    docker+httpd的安装
    访问GitLab的PostgreSQL数据库,查询、修改、替换等操作
    docker+rabbitmq的安装
    docker+elasticsearch的安装
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9697026.html
Copyright © 2011-2022 走看看