zoukankan      html  css  js  c++  java
  • BZOJ 3672 NOI2014 购票

    这题好神啊..好神啊...好神啊...

    首先列出N2的DP方程较易.

    从DP方程很容易看出来是斜率优化.

    如何进一步优化?

    考虑对当前点以上的链建立一个下凸包.

    维护凸包就可以,但不是很好写.

    观察到方程可以必然由它的祖先节点转移.很像Cash那道题.

    尝试CDQ分治,每次先递归处理根所在的子树.

    然后用根所在的子树,对当前点更新答案,对其他点进行根据dis-lim排序,维护栈即可.

    考虑到复杂度,我们需要对树进行点分治.

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    #include<string>
    #include<iomanip>
    #include<algorithm>
    #include<map>
    using namespace std;
    #define ll long long
    #define FILE "dealing"
    #define up(i,j,n) for(int i=j;i<=n;++i)
    #define db double
    #define uint unsigned ll
    #define eps 1e-12
    #define pii pair<ll,ll>
    ll read(){
    	ll x=0,f=1,ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	return f*x;
    }
    const ll maxn=200500,limit=1e6,mod=(ll)(7+1e9+0.1);
    const ll inf=(ll)(1e18);
    template<class T>bool cmax(T& a,T b){return a<b?a=b,true:false;}
    template<class T>bool cmin(T& a,T b){return a>b?a=b,true:false;}
    template<class T>T min(T& a,T& b){return a<b?a:b;}
    template<class T>T max(T& a,T& b){return a>b?a:b;}
    int n,m;
    ll fa[maxn],p[maxn],q[maxn],lim[maxn],dis[maxn],dui[maxn],f[maxn];
    struct node{
    	int y,next,v;
    }e[maxn];
    int len,linkk[maxn];
    void insert(int x,int y,ll v){
    	e[++len].y=y;
    	e[len].v=v;
    	e[len].next=linkk[x];
    	linkk[x]=len;
    }
    int root=0,siz[maxn],vis[maxn],Max[maxn],cnt;
    struct Node{
    	ll val,id;
    }a[maxn];
    void dfs1(ll x){
    	siz[x]=1;
    	for(ll i=linkk[x];i;i=e[i].next){
    		dis[e[i].y]=dis[x]+e[i].v;
    		dfs1(e[i].y);
    		siz[x]+=siz[e[i].y];
    	}
    }
    void find_root(ll x,int S,ll& rt){
    	Max[x]=0,siz[x]=1;
    	for(ll i=linkk[x];i;i=e[i].next){
    		if(vis[e[i].y])continue;
    		find_root(e[i].y,S,rt);
    		siz[x]+=siz[e[i].y];
    		cmax(Max[x],siz[e[i].y]);
    	}
    	cmax(Max[x],S-siz[x]);
    	if(Max[x]<Max[rt]&&siz[x]>1)rt=x;
    }
    void dfs2(ll x){
    	a[++cnt].val=dis[x]-lim[x];
    	a[cnt].id=x;
    	for(ll i=linkk[x];i;i=e[i].next)
    		if(!vis[e[i].y])dfs2(e[i].y);
    }
    bool cmp(Node a,Node b){
    	return a.val>b.val;
    }
    ll upd(ll x,ll y){return f[y]+(dis[x]-dis[y])*p[x]+q[x];}
    db K(ll x,ll y){return (1.0*f[x]-f[y])/(dis[x]-dis[y]);}
    void solve(ll x,int S){
    	if(S==1)return;ll rt=0,now=0;
    	find_root(x,S,rt);
    	for(ll i=linkk[rt];i;i=e[i].next)
    		vis[e[i].y]=1;
    	solve(x,S-siz[rt]+1);
    	cnt=0;
    	for(ll i=linkk[rt];i;i=e[i].next)dfs2(e[i].y);
    	sort(a+1,a+cnt+1,cmp);
    	now=rt;
    	int tail=0,l,r,mid,pos;
    	for(ll i=1;i<=cnt;i++){
    		while(now!=fa[x]&&dis[a[i].id]-lim[a[i].id]<=dis[now]){
    			while(tail>1&&K(dui[tail],now)>=K(dui[tail],dui[tail-1]))tail--;
    			dui[++tail]=now;now=fa[now];
    		}
    		if(tail>0){
    			l=1,r=tail,pos=1;
    			while(l<=r){
    				mid=(l+r)>>1;if(mid==tail){pos=tail;break;}
    				if(K(dui[mid],dui[mid+1])>=p[a[i].id])l=mid+1,pos=mid+1;
    				else r=mid-1;
    			}
    			cmin(f[a[i].id],upd(a[i].id,dui[pos]));
    		}
    	}
    	for(ll i=linkk[rt];i;i=e[i].next)solve(e[i].y,siz[e[i].y]);
    }
    int main(){
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    	n=read();ll d=read();
    	up(i,2,n){
    		ll y=read(),v=read();
    		fa[i]=y;
    		insert(y,i,v);
    		p[i]=read(),q[i]=read();
    		lim[i]=read();
    	}
    	dfs1(1);Max[0]=n+1;
    	up(i,2,n)f[i]=inf;
    	solve(1,siz[1]);
    	up(i,2,n)printf("%lld
    ",f[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    高可用的MongoDB集群-实战篇
    【转载】特征选择常用算法综述
    【转载】Pytorch tutorial 之Datar Loading and Processing
    论文笔记系列-Well Begun Is Half Done:Generating High-Quality Seeds for Automatic Image Dataset Construction from Web
    重新定义Pytorch中的TensorDataset,可实现transforms
    【转载】机器学习之特征工程
    Pytorch里的CrossEntropyLoss详解
    Python日志模块logging用法
    【转载】如何进行数据变换
    【转载】使用sklearn优雅地进行数据挖掘
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6544308.html
Copyright © 2011-2022 走看看