zoukankan      html  css  js  c++  java
  • 【BZOJ1146】网络管理(主席树,树状数组)

    【BZOJ1146】网络管理(主席树,树状数组)

    题面

    BZOJ权限题,洛谷题面

    题解

    树上带修改主席树
    貌似和(Count On A Tree)那题很相似呀
    只需要套上一个树状数组来维护修改好就好了
    但是记住是用(dfs)来记录主席树的标号
    一定不要搞错了
    每一次修改只会影响他子数的值
    而在(dfs)序上就是连续的一段
    美滋滋的做完了

    #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 161000
    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 S[MAX<<1],Tot,TT[MAX];
    int lowbit(int x){return x&(-x);}
    struct Node{int ls,rs,v;}t[MAX<<8];
    int rt[MAX],tot,ln[MAX];
    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 Modify(int &now,int ff,int l,int r,int pos,int w)
    {
    	t[now=++tot]=t[ff];t[now].v+=w;
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	if(pos<=mid)Modify(t[now].ls,t[ff].ls,l,mid,pos,w);
    	else Modify(t[now].rs,t[ff].rs,mid+1,r,pos,w);
    }
    void PreModify(int K,int pos,int w){for(int i=K;i<=n;i+=lowbit(i))Modify(rt[i],rt[i],1,Tot,pos,w);}
    int tmp1[MAX<<1],tmp2[MAX<<1],t1,t2;
    int Query(int l,int r,int K)
    {
    	if(l==r)return l;
    	int mid=(l+r)>>1,ss=0;
    	for(int i=1;i<=t1;++i)ss+=t[t[tmp1[i]].rs].v;
    	for(int i=1;i<=t2;++i)ss-=t[t[tmp2[i]].rs].v;
    	if(ss>=K)
    	{
    		for(int i=1;i<=t1;++i)tmp1[i]=t[tmp1[i]].rs;
    		for(int i=1;i<=t2;++i)tmp2[i]=t[tmp2[i]].rs;
    		return Query(mid+1,r,K);
    	}
    	else
    	{
    		for(int i=1;i<=t1;++i)tmp1[i]=t[tmp1[i]].ls;
    		for(int i=1;i<=t2;++i)tmp2[i]=t[tmp2[i]].ls;
    		return Query(l,mid,K-ss);
    	}
    }
    int preQuery(int u,int v,int K)
    {
    	t1=t2=0;
    	for(int i=dfn[u];i;i-=lowbit(i))tmp1[++t1]=rt[i];
    	for(int i=dfn[v];i;i-=lowbit(i))tmp1[++t1]=rt[i];
    	int lca=LCA(u,v);
    	for(int i=dfn[lca];i;i-=lowbit(i))tmp2[++t2]=rt[i];
    	for(int i=dfn[fa[lca]];i;i-=lowbit(i))tmp2[++t2]=rt[i];
    	return Query(1,Tot,K);
    }
    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;ln[tim]=u;
    	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;
    }
    void dfs3(int u,int ff)
    {
    	PreModify(dfn[u],TT[u],1);
    	PreModify(low[u]+1,TT[u],-1);
    	for(int i=h[u];i;i=e[i].next)
    		if(e[i].v!=ff)dfs3(e[i].v,u);
    }
    struct Op{int k,a,b;}O[MAX];
    int main()
    {
    	n=read();Q=read();
    	for(int i=1;i<=n;++i)S[++Tot]=TT[i]=read();
    	for(int i=1;i<n;++i)
    	{
    		int u=read(),v=read();
    		Add(u,v);Add(v,u);
    	}
    	for(int i=1;i<=Q;++i)O[i].k=read(),O[i].a=read(),O[i].b=read();
    	for(int i=1;i<=Q;++i)if(O[i].k==0)S[++Tot]=O[i].b;
    	sort(&S[1],&S[Tot+1]);
    	Tot=unique(&S[1],&S[Tot+1])-S-1;
    	for(int i=1;i<=n;++i)TT[i]=lower_bound(&S[1],&S[Tot+1],TT[i])-S;
    	for(int i=1;i<=Q;++i)if(O[i].k==0)O[i].b=lower_bound(&S[1],&S[Tot+1],O[i].b)-S;
    	dfs1(1,0);dfs2(1,1);dfs3(1,1);
    	for(int i=1;i<=Q;++i)
    	{
    		if(O[i].k==0)
    		{
    			PreModify(dfn[O[i].a],TT[O[i].a],-1);
    			PreModify(low[O[i].a]+1,TT[O[i].a],1);
    			PreModify(dfn[O[i].a],O[i].b,1);
    			PreModify(low[O[i].a]+1,O[i].b,-1);
    			TT[O[i].a]=O[i].b;
    		}
    		else
    		{
    			int len=dep[O[i].a]+dep[O[i].b]-2*dep[LCA(O[i].a,O[i].b)]+1;
    			if(O[i].k>len){puts("invalid request!");continue;}
    			printf("%d
    ",S[preQuery(O[i].a,O[i].b,O[i].k)]);
    		}
    	}
    	return 0;	
    }
    
    
  • 相关阅读:
    Improve Your Study Habits
    js中的cookie的读写操作
    js中数组/字符串常用属性方法归纳
    前端的一些常用DOM和事件归纳
    关于scroll无法绑定的问题
    页面内锚点定位及跳转方法总结
    js共享onload事件
    JS获取终端屏幕、浏览窗口的相关信息
    jsonp跨域问题记录
    关于if/else if
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8416111.html
Copyright © 2011-2022 走看看