zoukankan      html  css  js  c++  java
  • Luogu4175 [CTSC2008]网络管理

    Solution

    发现每个点的修改是对子树有影响的,所以这是个区间改,单点查,所以考虑差分,转化为区间查,单点加

    使用主席树维护第 (k) 大,接着上树状数组维护 (dfn) 序即可

    实现的时候可以参考下方链接里面的内容来减少码量

    https://www.luogu.com.cn/blog/jiqimao/p4175-ti-xie

    (Code:)

    #include<bits/stdc++.h>
    using namespace std;
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
     		return res*f;
    	}
    	const int N=80000+10;
    	inline int lowbit(int x){return x&(-x);}
    	vector<int> g[N];
    	int fa[N][20],lg[N],dep[N],b[N<<1],m,T,in[N],out[N];
    	struct node{
    		int id,k,x,y,val,opt;
    	}q[N];
    	int c1,c2,c3,c4,t1[30],tim,t2[30],t3[30],t4[30],n,p[N];
    	struct tree{
    		int ls,rs,val;
    		#define ls(p) t[p].ls
    		#define rs(p) t[p].rs
    		#define val(p) t[p].val
    	}t[20000010];
    	int rt[N<<2],tot;
    	inline void push_up(int p){return val(p)=val(ls(p))+val(rs(p)),void();}
    	inline void update(int &p,int l,int r,int x,int v)
    	{
    		if(!p) p=++tot;
    		if(l==r) return val(p)+=v,void();
    		int mid=(l+r)>>1;
    		if(x<=mid) update(ls(p),l,mid,x,v);
    		else update(rs(p),mid+1,r,x,v);
    		return push_up(p);
    	}
    	inline int query(int l,int r,int k)
    	{
    		if(l==r) return l;
    		int mid=(l+r)>>1,sum=0;
    		for(int i=1;i<=c3;++i) sum+=val(rs(t3[i]));
    		for(int i=1;i<=c4;++i) sum+=val(rs(t4[i]));
    		for(int i=1;i<=c2;++i) sum-=val(rs(t2[i]));
    		for(int i=1;i<=c1;++i) sum-=val(rs(t1[i]));
    		if(k>sum)
    		{
    			for(int i=1;i<=c1;++i) t1[i]=ls(t1[i]);
    			for(int i=1;i<=c2;++i) t2[i]=ls(t2[i]);
    			for(int i=1;i<=c3;++i) t3[i]=ls(t3[i]);
    			for(int i=1;i<=c4;++i) t4[i]=ls(t4[i]);
    			return query(l,mid,k-sum);
    		}
    		else
    		{
    			for(int i=1;i<=c1;++i) t1[i]=rs(t1[i]);
    			for(int i=1;i<=c2;++i) t2[i]=rs(t2[i]);
    			for(int i=1;i<=c3;++i) t3[i]=rs(t3[i]);
    			for(int i=1;i<=c4;++i) t4[i]=rs(t4[i]);
    			return query(mid+1,r,k);
    		}
    	}
    	inline int lca(int x,int y)
    	{
    		if(dep[x]<dep[y]) swap(x,y);
    		while(dep[x]>dep[y]) x=fa[x][lg[dep[x]-dep[y]]-1];
    		if(x==y) return x;
    		for(int i=19;i>=0;--i) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
    		return fa[x][0];
    	}
    	inline int ask(int x,int y,int k)
    	{
    		c1=0,c2=0,c3=0,c4=0; 
    		int l=lca(x,y);
    		for(int i=in[fa[l][0]];i;i-=lowbit(i)) t1[++c1]=rt[i];
    		for(int i=in[l];i;i-=lowbit(i)) t2[++c2]=rt[i];
    		for(int i=in[x];i;i-=lowbit(i)) t3[++c3]=rt[i];
    		for(int i=in[y];i;i-=lowbit(i)) t4[++c4]=rt[i];
    		return query(1,m,k);
    	}
    	inline void dfs(int x,int fat)
    	{
    		dep[x]=dep[fat]+1; fa[x][0]=fat; in[x]=++tim; 
    		for(int i=1;(1<<i)<=dep[x];++i) fa[x][i]=fa[fa[x][i-1]][i-1];
    		int siz=g[x].size();
    		for(int i=0;i<siz;++i) if(g[x][i]!=fat) dfs(g[x][i],x);
    		return out[x]=tim,void();
    	}
    	
    	inline void change(int x,int pos,int val)
    	{
    		for(int i=x;i<=n;i+=lowbit(i)) update(rt[i],1,m,pos,val);
    		return ;
    	}
    	signed main()
    	{
    		for(int i=1;i<N;++i) lg[i]=lg[i-1]+((1<<lg[i-1])==i);
    		n=read(); T=read();
    		for(int i=1;i<=n;++i) p[i]=read(),b[++m]=p[i];
    		for(int i=1;i<n;++i) 
    		{
    			int u=read(),v=read();
    			g[u].push_back(v); g[v].push_back(u); 
    		}
    		for(int i=1;i<=T;++i)
    		{
    			q[i].opt=read();
    			if(q[i].opt) q[i].x=read(),q[i].y=read(),q[i].k=q[i].opt;
    			else q[i].id=read(),q[i].val=read(),b[++m]=q[i].val;
    		}
    		sort(b+1,b+m+1); m=unique(b+1,b+m+1)-b-1;
    		for(int i=1;i<=n;++i) p[i]=lower_bound(b+1,b+m+1,p[i])-b;
    		for(int i=1;i<=T;++i) if(!q[i].opt) q[i].val=lower_bound(b+1,b+m+1,q[i].val)-b;
    		dfs(1,0);
    		for(int i=1;i<=n;++i) change(in[i],p[i],1),change(out[i]+1,p[i],-1);
    		for(int i=1;i<=T;++i)
    		{
    			if(q[i].opt) 
    			{
    				int l=lca(q[i].x,q[i].y);
    				if(dep[q[i].x]+dep[q[i].y]-dep[l]*2+1<q[i].k) puts("invalid request!");
    				else printf("%d
    ",b[ask(q[i].x,q[i].y,q[i].k)]);
    			}
    			else
    			{
    				change(in[q[i].id],p[q[i].id],-1),change(out[q[i].id]+1,p[q[i].id],1);
    				p[q[i].id]=q[i].val;
    				change(in[q[i].id],p[q[i].id],1); change(out[q[i].id]+1,p[q[i].id],-1);
    			}
    		}
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    
  • 相关阅读:
    为什么说性别字段不适合做索引?
    过程数据的记录(事务问题)
    两个系统操作同一条表记录涉及的事务的坑(依护系统)
    mybatis插件自动生成代码报错。
    ORACLE使用plsql和其他工具进行表结构和数据迁移
    ORACLE获取建表SQL
    学习英语的技巧
    Oracle的用户管理
    Jmeter做压力测试
    强烈推荐(原创亲测)!!!Fiddler抓取https设置详解(图文)
  • 原文地址:https://www.cnblogs.com/yspm/p/12707658.html
Copyright © 2011-2022 走看看