zoukankan      html  css  js  c++  java
  • CF Contest 526 G. Spiders Evil Plan 长链剖分维护贪心

    LINK:Spiders Evil Plan

    非常巧妙的题目。

    选出k条边使得这k条边的路径覆盖x且覆盖的边的边权和最大。

    类似于桥那道题还是选择2k个点 覆盖x那么以x为根做长链剖分即可。

    不过这样过不了。

    还是考虑树的直径 可以发现覆盖x的那些点一定有一个是树的直径的两端之一。

    所以我们直接对两条直径分别做这个东西然后想办法覆盖x.

    如果y条边x还没被覆盖。

    可以发现此时调整只有两种情况。

    1. 去掉长度最小的链然后把x所在的最长链加上去。

    2. 可以把x向上的被加入的链的下半部分去掉换成x.

    由于边权不为1 所以无法直接跳长链。

    考虑倍增即可。

    const int MAXN=100010;
    int n,len,Q;
    int Log[MAXN];
    int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1],e[MAXN<<1];
    inline void add(int x,int y,int z)
    {
    	ver[++len]=y;
    	nex[len]=lin[x];
    	lin[x]=len;
    	e[len]=z;
    }
    struct wy
    {
    	int d[MAXN],dis[MAXN],son[MAXN],mx[MAXN],ans[MAXN],c[MAXN];
    	int f[MAXN][20],cnt,rt,maxx;;
    	pii s[MAXN];
    	inline void dfs(int x,int fa,int op)
    	{
    		if(op)
    		{
    			f[x][0]=fa;mx[x]=dis[x];
    			d[x]=d[fa]+1;
    			rep(1,Log[d[x]],i)f[x][i]=f[f[x][i-1]][i-1];
    		}
    		if(!op&&dis[x]>dis[rt]){rt=x;}
    		go(x)
    		{
    			if(tn==fa)continue;
    			dis[tn]=dis[x]+e[i];
    			dfs(tn,x,op);
    			if(op&&mx[tn]>mx[x])
    			{
    				mx[x]=mx[tn];
    				son[x]=tn;
    			}
    		}
    	}
    	inline void dp(int x,int fa)
    	{
    		if(x==fa){s[++cnt]=mk(mx[x]-dis[f[x][0]],x);}
    		if(son[x])dp(son[x],fa);
    		go(x)if(tn!=f[x][0]&&tn!=son[x])dp(tn,tn);
    	}
    	inline void init(int x)
    	{
    		dfs(x,0,0);dis[rt]=0;
    		dfs(rt,0,1);dp(rt,rt);
    		sort(s+1,s+cnt+1);
    		for(int i=1,j=cnt;i<=cnt;++i,--j)
    		{
    			ans[i]=ans[i-1]+s[j].F;
    			for(int k=s[j].S;k;k=son[k])c[k]=i;
    		}
    	}
    	inline int calc1(int x,int y)//x所在长链替换y-1条长链
    	{
    		--y;
    		int w=x;
    		fep(Log[d[w]],0,i)if(c[f[w][i]]>y)w=f[w][i];
    		w=f[w][0];return ans[y]+mx[x]-dis[w];
    	}
    	inline int calc2(int x,int y)//向上的第一个长链的下半部分被替换掉.
    	{
    		int w=x;
    		fep(Log[d[x]],0,i)if(c[f[w][i]]>y)w=f[w][i];
    		w=f[w][0];return ans[y]+mx[x]-mx[w];
    	}
    	inline int query(int x,int y)
    	{
    		y=y*2-1;
    		if(y>=cnt)return ans[cnt];
    		if(c[x]<=y)return ans[y];
    		return max(calc1(x,y),calc2(x,y));
    	}
    	
    }t[2];
    int main()
    {
    	freopen("1.in","r",stdin);
    	get(n);get(Q);
    	rep(2,n,i)
    	{
    		int get(x),get(y),get(z);
    		add(x,y,z);add(y,x,z);
    		Log[i]=Log[i>>1]+1;
    	}
    	t[0].init(1);t[1].init(t[0].rt);
    	int ans=0;
    	rep(1,Q,i)
    	{
    		int x,y;
    		get(x);get(y);
    		x=(x+ans-1)%n+1;
    		y=(y+ans-1)%n+1;
    		ans=max(t[0].query(x,y),t[1].query(x,y));
    		put(ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Spring基础知识
    Hibernate基础知识
    Struts2基础知识
    在eclipse里头用checkstyle检查项目出现 File contains tab characters (this is the first instance)原因
    java后台获取cookie里面值得方法
    ckplayer 中的style.swf 中的 style.xml 中的修改方法
    java hql case when 的用法
    Windows下Mongodb安装及配置
    Mongodb中经常出现的错误(汇总)child process failed, exited with error number
    Mac 安装mongodb
  • 原文地址:https://www.cnblogs.com/chdy/p/12770291.html
Copyright © 2011-2022 走看看