【BZOJ】 [ZJOI2008]树的统计Count-树链剖分

传送门:BZOJ1036-树的统计


题意

一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身


输入

输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有
一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作
的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。


题解

树链剖分+线段树水题,dfs序


代码

#include<bits/stdc++.h>
using namespace std;
const int N=3e4+10;
typedef long long ll;
int n,m,T,df[N],cnt;
ll mx[N<<4],sum[N<<4],v[N],ret,ss;
int head[N],to[N<<1],nxt[N<<1],tag[N],tot;
int son[N],f[N],sz[N],d[N],top[N];
char st[10];

inline int read()
{
    char ch=getchar();int x=0,f=1;
    while(ch<'0' || ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*f;
}

inline void lk(int u,int v){
  to[++tot]=v;nxt[tot]=head[u];head[u]=tot;
  to[++tot]=u;nxt[tot]=head[v];head[v]=tot;
}

inline void swa(int &x,int &y){int t=x;x=y;y=t;}
inline int min(int x,int y){return x<y?x:y;}
inline ll max(ll x,ll y){return x>y?x:y;}
inline void update(int k)
{
    sum[k]=sum[k<<1]+sum[k<<1|1];
    mx[k]=max(mx[k<<1],mx[k<<1|1]);
}

inline void dfs(int x,int fa,int depth)
{
    f[x]=fa;d[x]=depth;sz[x]=1;
    for(int i=head[x];i;i=nxt[i]){
        if(to[i]==fa) continue;
        dfs(to[i],x,depth+1);
        sz[x]+=sz[to[i]];
        if(son[x]==0 || sz[son[x]]<sz[to[i]]) son[x]=to[i];
    }
}

inline void dfb(int x,int tp)
{
    top[x]=tp;df[x]=++cnt;
    if(son[x]==0) return;
    dfb(son[x],tp);
    for(int i=head[x];i;i=nxt[i]){
        if(to[i]==f[x] || to[i]==son[x]) continue;
        dfb(to[i],to[i]);
    }
}

inline void build(int k,int l,int r)
{
    if(l==r){sum[k]=mx[k]=v[tag[l]];return;}
    int mid=(l+r)>>1;
    build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    update(k);
}

inline void change(int k,int l,int r,int pos,int val)
{
    if(l==r){mx[k]=sum[k]=val;return;}
    int mid=(l+r)>>1;
    if(pos<=mid) change(k<<1,l,mid,pos,val);
    else change(k<<1|1,mid+1,r,pos,val);
    update(k);
}

inline void getmax(int k,int l,int r,int L,int R)
{
    if(l>=L && r<=R){ret=max(ret,mx[k]);return;}
    int mid=(l+r)>>1;
    if(L<=mid) getmax(k<<1,l,mid,L,R);
    if(R>mid) getmax(k<<1|1,mid+1,r,L,R);
}

inline void askmax(int x,int y)
{
    ret=-30001;
    while(top[x]!=top[y]){
         if(d[top[x]]<d[top[y]]) swa(x,y);
         getmax(1,1,n,df[top[x]],df[x]);
         x=f[top[x]];
    }
    if(d[x]<d[y]) swa(x,y);
    getmax(1,1,n,df[y],df[x]);
    printf("%lld\n",ret);
}

inline void getsum(int k,int l,int r,int L,int R)
{
    if(l>=L && r<=R){ss+=sum[k];return;}
    int mid=(l+r)>>1;
    if(L<=mid) getsum(k<<1,l,mid,L,R);
    if(R>mid) getsum(k<<1|1,mid+1,r,L,R);
}

inline void asksum(int x,int y)
{
   ss=0;
   while(top[x]!=top[y]){
      if(d[top[x]]<d[top[y]]) swa(x,y);
      getsum(1,1,n,df[top[x]],df[x]);
      x=f[top[x]];
   }    
   if(d[x]<d[y]) swa(x,y);
   getsum(1,1,n,df[y],df[x]);
   printf("%lld\n",ss);
} 

int main(){
    int i,j,u,x,y;
    n=read();
    for(i=1;i<n;i++){u=read();lk(u,read());}
    for(i=1;i<=n;i++) v[i]=read();
    dfs(1,0,0);dfb(1,1);
    for(i=1;i<=n;i++) tag[df[i]]=i;
    build(1,1,n); 
    T=read();
    while(T--){
        scanf("%s",st);
        x=read(),y=read();
        if(st[0]=='C') change(1,1,n,df[x],y);
        else if(st[1]=='M') askmax(x,y);
        else asksum(x,y);
    }
    return 0;
}
weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值