zoukankan      html  css  js  c++  java
  • 【CF150E】 Freezing with Style

    题目

    中位数显然是可以二分的,我们二分一个(mid),所有边权不小于(mid)设成(1),否则设为(-1);如果能找到一条边权和不小于(0)的路径,就说明中位数可以更大;于是这显然可以长链剖分+线段树

    第一次写长剖线段树,就当写个板子了

    代码

    #include<bits/stdc++.h>
    #define re register
    #define min(a,b) ((a)<(b)?(a):(b))
    #define max(a,b) ((a)>(b)?(a):(b))
    const int maxn=1e5+5;
    inline int read() {
    	char c=getchar();int x=0;while(c<'0'||c>'9')c=getchar();
    	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    struct node{int mx,t;}a[maxn*3];
    int l[maxn*3],r[maxn*3],tag[maxn*3];
    struct E{int v,nxt,w;}e[maxn<<1];
    int dfn[maxn],len[maxn],son[maxn],head[maxn];
    int n,num,L,R,rx,ry,X,Y,flag,__,val[maxn],wt[maxn];
    inline void add(int x,int y,int w) {
    	e[++num].v=y;e[num].nxt=head[x];head[x]=num;e[num].w=w;
    }
    void dfs1(int x,int fa) {
    	for(re int i=head[x];i;i=e[i].nxt) {
    		if(e[i].v==fa) continue;dfs1(e[i].v,x);
    		if(len[e[i].v]>len[son[x]]) son[x]=e[i].v,wt[x]=e[i].w;
    	}
    	len[x]=len[son[x]]+1;
    }
    void dfs2(int x) {
    	dfn[x]=++__;if(!son[x])return;dfs2(son[x]);
    	for(re int i=head[x];i;i=e[i].nxt)if(!dfn[e[i].v])dfs2(e[i].v);
    }
    inline node operator+(const node &A,const node &B) {return A.mx>B.mx?A:B;}
    void build(int x,int y,int i) {
    	l[i]=x,r[i]=y;if(x==y)return;
    	int mid=x+y>>1;build(x,mid,i<<1),build(mid+1,y,i<<1|1);
    }
    void clr(int i) {
    	tag[i]=a[i].t=0;a[i].mx=-n;
    	if(l[i]==r[i])return;clr(i<<1),clr(i<<1|1);
    }
    inline void mix(int i,int v) {tag[i]+=v;a[i].mx+=v;}
    inline void pushdown(int i) {
    	if(!tag[i])return;
    	mix(i<<1,tag[i]),mix(i<<1|1,tag[i]);tag[i]=0;
    }
    node qry(int x,int y,int i) {
    	if(x<=l[i]&&y>=r[i])return a[i];int mid=l[i]+r[i]>>1;pushdown(i);
    	if(y<=mid)return qry(x,y,i<<1);if(x>mid)return qry(x,y,i<<1|1);
    	return qry(x,y,i<<1)+qry(x,y,i<<1|1);
    }
    void chg(int x,int y,int v,int i) {
    	if(x<=l[i]&&y>=r[i]) {mix(i,v);return;}
    	int mid=l[i]+r[i]>>1;pushdown(i);
    	if(x<=mid)chg(x,y,v,i<<1);if(y>mid)chg(x,y,v,i<<1|1);
    	a[i]=a[i<<1]+a[i<<1|1];
    }
    void mof(int pos,int i,node v) {
    	if(l[i]==r[i]) {a[i]=a[i]+v;return;}
    	int mid=l[i]+r[i]>>1;pushdown(i);
    	if(pos<=mid)mof(pos,i<<1,v);else mof(pos,i<<1|1,v);a[i]=a[i<<1]+a[i<<1|1];
    }
    void Dfs(int x,int fa,int mid) {
    	if(flag)return;
    	mof(dfn[x],1,(node){0,x});if(!son[x])return;
    	Dfs(son[x],x,mid);
    	chg(dfn[x]+1,dfn[x]+len[x]-1,wt[x]>=mid?1:-1,1);
    	if(L<len[x]) {
    		node ask=qry(dfn[x]+L,dfn[x]+min(len[x]-1,R),1);
    		if(ask.mx>=0) {flag=1;X=x,Y=ask.t;return;}
    	}
    	for(re int i=head[x];i;i=e[i].nxt) {
    		if(e[i].v==fa||e[i].v==son[x])continue;Dfs(e[i].v,x,mid);
    		int v=(e[i].w>=mid?1:-1);
    		for(re int j=1;j<=len[e[i].v];++j) {
    			node c=qry(dfn[e[i].v]+j-1,dfn[e[i].v]+j-1,1);
    			c.mx+=v;if(L-j>=len[x]||j>R) continue;
    			node ask=qry(dfn[x]+max(0,L-j),dfn[x]+min(len[x]-1,R-j),1);
    			if(ask.mx+c.mx>=0) {X=c.t,Y=ask.t;flag=1;return;}
    		}
    		for(re int j=1;j<=len[e[i].v];++j) {
    			node c=qry(dfn[e[i].v]+j-1,dfn[e[i].v]+j-1,1);
    			c.mx+=v;mof(dfn[x]+j,1,c);
    		}
    	}
    }
    inline int chk(int mid) {
    	clr(1);flag=0;Dfs(1,0,mid);return flag;
    }
    int main() {
    	n=read(),L=read(),R=read();
    	for(re int x,y,w,i=1;i<n;i++) {
    		x=read(),y=read(),w=read();
    		add(x,y,w),add(y,x,w);val[i]=w;
    	} 
    	dfs1(1,0);dfs2(1);build(1,n,1);std::sort(val+1,val+n);
    	int rr=std::unique(val+1,val+n)-val-1,ll=1;
    	while(ll<=rr) {
    		int mid=ll+rr>>1;
    		if(chk(val[mid])) {
    			ll=mid+1;rx=X,ry=Y;
    		}
    		else rr=mid-1;
    	}
    	printf("%d %d
    ",rx,ry);return 0;
    }
    
  • 相关阅读:
    vue 防抖 节流
    数组取最小数据长度,确定长度截取,看是否全等 ,全等通过不等提示,需要拆分
    数组去重取不重复的数据
    vue
    vue2.0 子组件获取父组件值 使用v-model可渲染不能更改
    使用mpvue 开发小程序 遇到的坑
    ztree 样式更改
    vue 跨域请求
    记录 vue2.0 再使用过程中遇到的问题
    bug
  • 原文地址:https://www.cnblogs.com/asuldb/p/12174399.html
Copyright © 2011-2022 走看看