• [清华集训2016]汽水


    [清华集训2016]汽水

    UOJ
    BZOJ
    这是一个常数大的人过不了的算法
    分数规划套点分治,暴力离散化然后树状数组查询
    复杂度:(O(nlog^3n))
    所以有大佬教我卡卡常嘛??

    #define lb(i) (i&-i)
    #define ll long long
    #include<bits/stdc++.h>
    using namespace std;
    const int _=5e4+5;
    const ll inf=1e18;
    inline ll re(){
        ll x=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*w;
    }
    int n,num,cnt,tot,rt,Rt,ok;
    int h[_],ms[_],sz[_],vis[_];
    ll k,l,r=inf,mid,ans;
    ll val[_],o[_<<1],f[_],g[_],t[_<<1];
    vector<int>son[_];
    struct edge{int to,next;ll w;}e[_<<1];
    inline void link(int u,int v,ll w){
    	e[++cnt]=(edge){v,h[u],w},h[u]=cnt;
    	e[++cnt]=(edge){u,h[v],w},h[v]=cnt;
    }
    inline void add(int i,ll v){while(i<=num)t[i]=max(t[i],v),i+=lb(i);}
    inline void mdf(int i,ll v){while(i<=num)t[i]=v,i+=lb(i);}
    inline ll qmax(int i){ll res=-inf;while(i)res=max(res,t[i]),i-=lb(i);return res;}
    void qrt(int u,int fa){
    	sz[u]=1,ms[u]=0;
    	for(int i=h[u];i;i=e[i].next){
    		int v=e[i].to;
    		if(v==fa||vis[v])continue;
    		qrt(v,u),sz[u]+=sz[v],
    		ms[u]=max(ms[u],sz[v]);
    	}
    	ms[u]=max(ms[u],tot-sz[u]);
    	if(ms[u]<ms[rt])rt=u;
    }
    void bu(int u){
    	vis[u]=1;int now=tot;
    	for(int i=h[u];i;i=e[i].next){
    		int v=e[i].to;
    		if(vis[v])continue;
    		if(sz[u]<sz[v])tot=now-sz[u];
    		else tot=sz[v];rt=0,qrt(v,0);
    		son[u].push_back(rt);bu(rt);
    	}
    }
    void dfs(int u,int fa,int dep,ll dis){
    	val[u]=dis+dep*mid;
    	f[u]=o[++num]=dis-dep*mid;
    	g[u]=o[++num]=-f[u];
    	for(int i=h[u];i;i=e[i].next){
    		int v=e[i].to;
    		if(v==fa||vis[v])continue;
    		dfs(v,u,dep+1,dis+e[i].w);
    	}
    }
    void calc(int u,int fa){
    	g[u]=lower_bound(o+1,o+num+1,g[u])-o;
    	if(qmax(g[u]-1)+val[u]>0)ok=1;
    	for(int i=h[u];i;i=e[i].next){
    		int v=e[i].to;
    		if(v^fa&&!vis[v])calc(v,u);
    	}
    }
    void pre(int u,int fa){
    	f[u]=lower_bound(o+1,o+num+1,f[u])-o;
    	add(f[u],val[u]);
    	for(int i=h[u];i;i=e[i].next){
    		int v=e[i].to;
    		if(v^fa&&!vis[v])pre(v,u);
    	}
    }
    void clear(int u,int fa){
    	mdf(f[u],-inf);
    	for(int i=h[u];i;i=e[i].next){
    		int v=e[i].to;
    		if(v^fa&&!vis[v])clear(v,u);
    	}
    }
    void solve(int u){
    	vis[u]=1;num=0;
    	dfs(u,0,0,0);
    	sort(o+1,o+num+1);
    	num=unique(o+1,o+num+1)-o-1;
    	f[u]=lower_bound(o+1,o+num+1,0)-o;
    	add(f[u],0);
    	for(int i=h[u];i;i=e[i].next){
    		int v=e[i].to;if(vis[v])continue;
    		calc(v,u);if(ok)return;pre(v,u);
    	}
    	mdf(f[u],-inf);
    	for(int i=h[u];i;i=e[i].next){
    		int v=e[i].to;
    		if(!vis[v])clear(v,u);
    	}
    	for(int i=h[u],j=0;i;i=e[i].next){
    		int v=e[i].to;if(ok)return;
    		if(!vis[v])solve(son[u][j++]);
    	}
    }
    int main(){
        tot=ms[0]=n=re();k=re();
    	for(int i=1;i<n;++i){
    		int u=re(),v=re();ll w=re()-k;
    		link(u,v,w);r=min(r,abs(w))+1;
    	}
    	qrt(1,0);bu(Rt=rt);
    	while(l<=r){
    		mid=(l+r)>>1;
    		memset(vis,0,sizeof(vis));
    		memset(t,-0x7f,sizeof(t));
    		ok=0;solve(Rt);
    		if(ok)ans=r=mid-1;
    		else l=mid+1;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    pyecharts的版本问题
    世界各国中英文名称映射字典(pyecharts)
    爬取世界疫情数据绘制疫情可视化地图
    好好写,好好干-PHP基础(二)
    自罚一杯-PHP基础(一)
    又是一周-AJAX(三)
    我懒蛋又回来了!-PDO
    退役了退役了-AJAX
    睡觉问题早晚成为我顶头疼的问题。。。-PHP
    其实今天没有欲望..-MySQLi
  • 原文地址:https://www.cnblogs.com/sdzwyq/p/10076475.html
Copyright © 2020-2023  润新知