BZOJ1146[CTSC2008]网络管理Network

BZOJ1146[CTSC2008]网络管理Network

题面:BZOJ

解析

为什么要用树套树啊?整体二分多好,好写又好想。
还是说一下树套树吧,因为博主做这道题本来是奔着这方法来的,结果却用了离线算法水过。
先考虑不带修改的做法。考虑用dfs入栈出栈序上的主席树,入栈+1,出栈-1,那么每一颗线段树对应的就是它到根的链的权值线段树,那么查询就用lca去除贡献就可以了,复杂度是\(O(nlogn)\)。带修改呢?简单,套个树状数组就行了,复杂度多个log。
至于整体二分,博主他太懒了,不想写了,看代码吧。

代码


#include<cstdio>
#include<iostream>
#define N 80005
#define mid ((l+r)>>1)
#define lc c[u][0]
#define rc c[u][1]
using namespace std;
inline int In(){
    char c=getchar(); int x=0,ft=1;
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') ft=-1;
    for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
    return x*ft;
}
int n,m,val[N];
int h[N],e_tot=0;
struct E{ int to,nex; }e[N<<1];
inline void add(int u,int v){
    e[++e_tot]=(E){v,h[u]}; h[u]=e_tot;
    e[++e_tot]=(E){u,h[v]}; h[v]=e_tot;
}
int d[N],fa[N],sz[N],son[N],top[N];
void dfs1(int u,int pre,int dep){
    d[u]=dep; fa[u]=pre; sz[u]=1;
    for(int i=h[u],v;i;i=e[i].nex){
        v=e[i].to; if(v==fa[u]) continue;
        dfs1(v,u,dep+1); sz[u]+=sz[v];
        if(!son[u]||sz[son[u]]<sz[v]) son[u]=v;
    }
}
int dfn[N],dfs_clock=0;
void dfs2(int u,int pre){
    top[u]=pre; dfn[u]=++dfs_clock;
    if(son[u]) dfs2(son[u],pre);
    for(int i=h[u],v;i;i=e[i].nex){
        v=e[i].to; if(v!=son[u]&&v!=fa[u]) dfs2(v,v);
    }
}
inline int LCA(int x,int y){
    while(top[x]!=top[y]){
        if(d[top[x]]<d[top[y]]) swap(x,y);
        x=fa[top[x]];
    }
    return d[x]>d[y]?y:x;
}
int rt=0,T_tot=0,c[N<<1][2],lz[N<<1];
void Update(int L,int R,int C,int l,int r,int& u){
    if(!u) u=++T_tot;
    if(L<=l&&r<=R){ lz[u]+=C; return; }
    if(L<=mid) Update(L,R,C,l,mid,lc);
    if(R>mid) Update(L,R,C,mid+1,r,rc);
}
int Query(int G,int l,int r,int u){
    if(!u||!G) return 0; if(l==r) return lz[u];
    if(G<=mid) return lz[u]+Query(G,l,mid,lc);
    else return lz[u]+Query(G,mid+1,r,rc);
}
inline void Add(int x,int C){
    Update(dfn[x],dfn[x]+sz[x]-1,C,1,n,rt);
}
inline int Query(int x,int y){
    int lca=LCA(x,y);
    return Query(dfn[x],1,n,rt)+Query(dfn[y],1,n,rt)-
    Query(dfn[lca],1,n,rt)-Query(dfn[fa[lca]],1,n,rt);
}
int qc=0,id[N*3],t1[N*3],t2[N*3],ans[N*3];
struct Q{ int op,i,j,k; }q[N*3];
void Solve(int l,int r,int ql,int qr){
    if(ql>qr) return;
    if(l==r){ for(int i=ql;i<=qr;++i) ans[id[i]]=l; return; }
    int c1=0,c2=0;
    for(int i=ql,u;i<=qr;++i){
        u=id[i];
        if(q[u].op==0){
            if(q[u].k>mid) Add(q[u].i,q[u].j),t1[++c1]=u;
            else t2[++c2]=u;
        }
        else{
            int S=Query(q[u].i,q[u].j);
            if(q[u].k<=S) t1[++c1]=u;
            else q[u].k-=S,t2[++c2]=u;
        }
    }
    for(int i=ql,u;i<=qr;++i){
        u=id[i];
        if(q[u].op==0&&q[u].k>mid)
        Add(q[u].i,-q[u].j);
    }
    for(int i=1;i<=c1;++i) id[ql+i-1]=t1[i];
    for(int i=1;i<=c2;++i) id[ql+c1+i-1]=t2[i];
    Solve(mid+1,r,ql,ql+c1-1); Solve(l,mid,ql+c1,qr);
}
int main(){
    n=In(); m=In();
    for(int i=1;i<=n;++i){
        val[i]=In();
        q[++qc]=(Q){0,i,1,val[i]};
    }
    for(int i=1;i<n;++i) add(In(),In());
    dfs1(1,0,0); dfs2(1,1);
    for(int i=1,op,a,b;i<=m;++i){
        op=In(); a=In(); b=In();
        if(op==0){
            q[++qc]=(Q){0,a,-1,val[a]};
            q[++qc]=(Q){0,a,1,b};
            val[a]=b;
        }
        else q[++qc]=(Q){1,a,b,op};
    }
    for(int i=1;i<=qc;++i) id[i]=i;
    Solve(-1,1e8,1,qc);
    for(int i=1;i<=qc;++i) if(q[i].op==1){
        if(ans[i]!=-1) printf("%d\n",ans[i]);
        else printf("invalid request!\n");
    }
    return 0;
}

转载于:https://www.cnblogs.com/pkh68/p/10555137.html

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、付费专栏及课程。

余额充值