zoukankan      html  css  js  c++  java
  • 【BZOJ1146】网络管理(整体二分)

    【BZOJ1146】网络管理(整体二分)

    题面

    良心洛谷,有BZOJ权限题

    题解

    要看树套树的戳这里

    毕竟是:智商不够数据结构来补

    所以,
    我们来当一回智商够的选手

    听说主席树的题目大部分都可以整体二分

    这题丢进去整体二分就行了
    只需要查询树上贡献的前缀和
    但是,对于这种带修改的
    不能够直接修改
    每一个修改操作必须拆成两个:
    一个删掉原来的修改,一个加入现在的修改
    否则就会重复计算贡献从而(gg)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 81000
    #define lson (now<<1)
    #define rson (now<<1|1)
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Line{int v,next;}e[MAX<<1];
    int h[MAX],cnt=1;
    inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
    int dfn[MAX],low[MAX],fa[MAX],size[MAX],hson[MAX],dep[MAX],top[MAX];
    int tim,n,Q;
    int LCA(int u,int v)
    {
        while(top[u]!=top[v])
            dep[top[u]]<dep[top[v]]?v=fa[top[v]]:u=fa[top[u]];
        return dep[u]<dep[v]?u:v;
    }
    void dfs1(int u,int ff)
    {
        size[u]=1;fa[u]=ff;dep[u]=dep[ff]+1;
        for(int i=h[u];i;i=e[i].next)
        {
            if(e[i].v==ff)continue;
            dfs1(e[i].v,u);
            size[u]+=size[e[i].v];
            if(size[e[i].v]>size[hson[u]])hson[u]=e[i].v;
        }
    }
    void dfs2(int u,int tp)
    {
        top[u]=tp;dfn[u]=++tim;
        if(hson[u])dfs2(hson[u],tp);
        for(int i=h[u];i;i=e[i].next)
        {
            if(e[i].v==fa[u]||e[i].v==hson[u])continue;
            dfs2(e[i].v,e[i].v);
        }
        low[u]=tim;
    }
    int sum,ans[MAX];
    struct Op{int k,a,b,id,opt;}O[MAX<<1],p1[MAX<<1],p2[MAX<<1];
    int c[MAX],TT[MAX];
    int lowbit(int x){return x&(-x);}
    void add(int x,int w){while(x<=n)c[x]+=w,x+=lowbit(x);}
    int getsum(int x){int ret=0;while(x)ret+=c[x],x-=lowbit(x);return ret;}
    int jump(int u,int v)
    {
    	int ret=0;
    	while(top[u]!=top[v])
    	{
    		if(dep[top[u]]<dep[top[v]])swap(u,v);
    		ret+=getsum(dfn[u])-getsum(dfn[top[u]]-1);
    		u=fa[top[u]];
    	}
    	if(dep[u]<dep[v])swap(u,v);
    	ret+=getsum(dfn[u])-getsum(dfn[v]-1);
    	return ret;
    }
    void Work(int L,int R,int l,int r)
    {
    	if(L>R)return;
    	if(l==r)
    	{
    		for(int i=L;i<=R;++i)
    			if(!O[i].opt&&ans[O[i].id]!=-1)ans[O[i].id]=l;
    		return;
    	}
    	int mid=(l+r)>>1;
    	int t1=0,t2=0;
    	for(int i=L;i<=R;++i)
    	{
    		if(O[i].k==0)
    		{
    			if(O[i].b<=mid)p1[++t1]=O[i];
    			else p2[++t2]=O[i],add(dfn[O[i].a],O[i].id);
    		}
    		else
    		{
    			int ss=jump(O[i].a,O[i].b);
    			if(ss>=O[i].k)p2[++t2]=O[i];
    			else O[i].k-=ss,p1[++t1]=O[i];
    		}
    	}
    	for(int i=L;i<=R;++i)if(O[i].opt&&O[i].b>mid)add(dfn[O[i].a],-O[i].id);
    	for(int i=1;i<=t1;++i)O[L+i-1]=p1[i];
    	for(int i=1;i<=t2;++i)O[L+t1+i-1]=p2[i];
    	Work(L,L+t1-1,l,mid);Work(L+t1,R,mid+1,r);
    }
    int main()
    {
        n=read();Q=read();
    	int Cnt=0;
    	for(int i=1;i<=n;++i)
    	{
    		TT[i]=read();
    		O[++Cnt]=(Op){0,i,TT[i],1,1};
    	}
    	for(int i=1;i<n;++i)
    	{
    		int u=read(),v=read();
    		Add(u,v);Add(v,u);
    	}
    	dfs1(1,0);dfs2(1,1);
    	for(int i=1;i<=Q;++i)
    	{
    		int k=read(),a=read(),b=read();
    		if(k)
    		{
    			O[++Cnt]=(Op){k,a,b,++sum,0};
    			int len=dep[O[Cnt].a]+dep[O[Cnt].b]-2*dep[LCA(O[Cnt].a,O[Cnt].b)]+1;
    			if(O[Cnt].k>len)ans[O[Cnt].id]=-1;
    		}
    		else
    		{
    			O[++Cnt]=(Op){0,a,TT[a],-1,1};
    			O[++Cnt]=(Op){0,a,TT[a]=b,1,1};
    		}
    	}
    	Work(1,Cnt,1,1e8);
    	for(int i=1;i<=sum;++i)
    		ans[i]!=-1?printf("%d
    ",ans[i]):puts("invalid request!");
    	return 0;	
    }
    
    
  • 相关阅读:
    2. 环形路加油
    1. 元素累加
    开始在线练习50题。
    C# 搜索关键词
    Python调用OpenCV几何变换
    Tensorflow加载多幅图像进一个tensor
    Cmake构建OpenCV测试例子
    Linux利用本地http下载解决一些需要联网下载的问题
    Python调用OpenCV算术操作
    Python调用OpenCV阈值化
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8417503.html
Copyright © 2011-2022 走看看