• [SDOI2016]游戏 树剖+李超树


    链接

    https://www.luogu.org/problemnew/show/P4069

    思路

    树剖+超哥线段树
    我已经自毙了,自闭了!!!!

    update

    上次抄了没认真看,这次考试又自毙了
    是一个细节的处理上一次没处理

    代码

    #include <bits/stdc++.h>
    #define ll long long
    #define ls rt<<1
    #define rs rt<<1|1
    using namespace std;
    const ll inf=123456789123456789LL;
    const ll N=5e5+7;
    ll read() {
    	ll x=0,f=1;char s=getchar();
    	for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    	for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    	return x*f;
    }
    ll n,m;
    struct edge {
    	ll v,nxt,q;
    }e[N<<1];
    ll head[N<<1],tot;
    void add(ll u,ll v,ll q) {
    	e[++tot].v=v;
    	e[tot].q=q;
    	e[tot].nxt=head[u];
    	head[u]=tot;
    }
    ll fa[N],dep[N],son[N],siz[N];
    ll dis[N];
    void dfs1(ll u,ll f) {
    	dep[u]=dep[f]+1;
    	siz[u]=1;
    	fa[u]=f;
    	for(ll i=head[u];i;i=e[i].nxt) {
    		ll v=e[i].v;
    		if(v==f) continue;
    		dis[v]=dis[u]+(ll)e[i].q;
    		dfs1(v,u);
    		siz[u]+=siz[v];
    		if(siz[son[u]]<siz[v]) son[u]=v;
    	}
    }
    ll idx[N],top[N],js;
    ll xxx[N];
    void dfs2(ll u,ll topf) {
    	idx[u]=++js;
    	xxx[js]=u;
    	top[u]=topf;
    	if(!son[u]) return;
    	dfs2(son[u],topf);
    	for(ll i=head[u];i;i=e[i].nxt) {
    		ll v=e[i].v;
    		if(!idx[v]) dfs2(v,v);
    	}
    }
    struct node {
    	ll l,r;
    	ll a,b,mi;
    }tr[N<<2];
    void build(ll l,ll r,ll rt) {
    	tr[rt].l=l,tr[rt].r=r;
    	tr[rt].mi=tr[rt].b=inf;
    	if(l==r) return;
    	ll mid=(l+r)>>1;
    	build(l,mid,ls);
    	build(mid+1,r,rs);
    }
    ll f(ll a,ll b,ll x) {
    	return a*dis[xxx[x]]+b;
    }
    #define f_l f(tr[rt].a,tr[rt].b,tr[rt].l)
    #define f_r f(tr[rt].a,tr[rt].b,tr[rt].r)
    void pushup(ll rt) {		
    	tr[rt].mi=min(tr[rt].mi,min(tr[ls].mi,tr[rs].mi));
    	tr[rt].mi=min(tr[rt].mi,min(f_l,f_r));
    }
    void modify(ll L,ll R,ll a,ll b,ll rt) {
    	if(L<=tr[rt].l&&tr[rt].r<=R) {
    		if(f_l<=f(a,b,tr[rt].l)&&f_r<=f(a,b,tr[rt].r)) return;
    		if(f_l>f(a,b,tr[rt].l)&&f_r>f(a,b,tr[rt].r)) {
    			tr[rt].a=a;
    			tr[rt].b=b;
    			tr[rt].mi=min(tr[rt].mi,min(f_l,f_r));
    			return;	
    		}
    		ll mid=(tr[rt].l+tr[rt].r)>>1;
    
    		if(tr[rt].a<=a) {
    			if(f(tr[rt].a,tr[rt].b,mid)>=f(a,b,mid)) {
    				swap(tr[rt].a,a);
    				swap(tr[rt].b,b);
    				modify(L,R,a,b,rs);
    			} else modify(L,R,a,b,ls);
    		} else {
    			if(f(tr[rt].a,tr[rt].b,mid)>=f(a,b,mid)) {
    				swap(tr[rt].a,a);
    				swap(tr[rt].b,b);
    				modify(L,R,a,b,ls);
    			} else modify(L,R,a,b,rs);
    		}
    		 tr[rt].mi= min(min(tr[ls].mi, tr[rs].mi), min(f_l,f_r));
    		// pushup(rt);
    		return;
    	}
    	ll mid=(tr[rt].l+tr[rt].r)>>1;
    	if(L<=mid) modify(L,R,a,b,ls);
    	if(R>mid) modify(L,R,a,b,rs);
    	pushup(rt);
    }
    
    ll query(ll L,ll R,ll rt) {
    	if(L<=tr[rt].l&&tr[rt].r<=R) {
    		return tr[rt].mi;
    	}
    	ll mid=(tr[rt].l+tr[rt].r)>>1;
    	ll ans=inf;
    	ans=min(ans,min(f(tr[rt].a,tr[rt].b,max(L,tr[rt].l)),f(tr[rt].a,tr[rt].b,min(tr[rt].r,R))));
    	if(L<=mid) ans=min(ans,query(L,R,ls));
    	if(R>mid) ans=min(ans,query(L,R,rs));
    	return ans;
    }
    ll lca(ll x,ll y) {
    	while(top[x]!=top[y]) {
    		if(dep[top[x]] < dep[top[y]]) swap(x,y);
    		x=fa[top[x]];				
    	}
    	if(dep[x]>dep[y]) swap(x,y);
    	return x;
    }
    void C(ll x,ll y,ll a,ll b) {
    	while(top[x]!=top[y]) {
    		if(dep[top[x]] < dep[top[y]]) swap(x,y);
    		modify(idx[top[x]],idx[x],a,b,1);
    		x=fa[top[x]];
    	}
    	if(dep[x]>dep[y]) swap(x,y);
    	modify(idx[x],idx[y],a,b,1);
    }
    void Q(ll x,ll y) {
    	ll ans=inf;
    	while(top[x]!=top[y]) {
    		if(dep[top[x]] < dep[top[y]]) swap(x,y);
    		ans=min(ans,query(idx[top[x]],idx[x],1));
    		x=fa[top[x]];
    	}
    	if(dep[x]>dep[y]) swap(x,y);
    	ans=min(ans,query(idx[x],idx[y],1));
    	printf("%lld
    ",ans);
    }
    int main() {		
    	n=read(),m=read();
    	for(ll i=1;i<n;++i) {
    		ll x=read(),y=read(),z=read();
    		add(x,y,z);
    		add(y,x,z);
    	}
    	dfs1(1,0);
    	dfs2(1,1);
    	build(1,n,1);
    	while(m--) {
    		ll opt=read();
    		if(opt==1) {
    			ll s=read(),t=read();
    			ll A=read(),B=read();
    			ll dsr=lca(s,t);
    			C(s,dsr,(ll)-A,1LL*dis[s]*A+B);
    			C(dsr,t,(ll)A,1LL*dis[s]*A-2LL*A*dis[dsr]+B);
    		} else {
    			ll s=read(),t=read();
    			Q(s,t);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Razor中@:和text
    Razor返回HTML字符串
    EPPlus使用
    ASP.NET MVC使用AllowAnonymous特性跳过授权验证
    下拉框获取json文件的数据
    SpringBoot 监听机制
    MybatisPlus Warpper实现复杂查询
    整合MybatisPlus心得
    MybatisPlus性能分析插件
    MybatisPlus物理删除、逻辑删除
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10358119.html
Copyright © 2020-2023  润新知