zoukankan      html  css  js  c++  java
  • P4655 [CEOI2017]Building Bridges

    P4655 [CEOI2017]Building Bridges

    为啥黑题没紫题难啊/kk,感觉这题30天之内会掉紫

    状态非常一眼&simple:设 (dp_i) 表示 (1,i) 联通的最小代价

    (s_n=sum_{i=1}^{n}w_i)

    转移非常一眼&simple:(dp_i=min{dp_j+(h_i-h_j)^2+s_{i-1}-s_j }(j<i))

    处理非常一眼&simple:(dp_i=min{dp_j+h_j^2-s_j-2h_ih_j }+h_i^2+s_{i-1})

    非常一眼&simple可以想到用李超树维护,把 (-2h_i) 当作斜率,(dp_j+h_j^2-s_j) 当作 (y) 轴截距,全部插到李超树里,就相当于取 (x=h_i) 时所有直线的最小值

    其实还可以斜率优化,但是那个 (w_i) 可能是负数不一定是凸壳,看别人要 cdq 分治,我感觉李超树简单多了,复杂度都是 (O(nlog n)),cdq分治写丑点还会变成 (O(nlog^2n))。。。

    第一次用 vim 写出黑题呢(其实这是用 vim 写的第二道题)。但是发现调试太累了,尤其是DS,就不用了qwq

    没抢到最优解,只有第三,不知道为啥第一名比我快 30ms ,方法都一样,一定是我人傻常数大。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef double db;
    #define mkp(x,y) make_pair(x,y)
    #define fi first
    #define se second
    #define pb(x) push_back(x)
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return f?x:-x;
    }
    #define N 100005
    #define M 1000005
    #define T (M<<2)
    #define inf 1000000000000000000ll
    int n,h[N],w[N],cnt,C;
    LL s[N],dp[N];
    int v[T];
    pair<int,LL>li[N];
    #define val(x,y) (1ll*li[x].fi*y+li[x].se)
    #define lc (p<<1)
    #define rc (p<<1|1)
    void update(int id,int l=1,int r=C,int p=1){
    	if(!v[p])return v[p]=id,void();
    	int mid=(l+r)>>1;
    	LL nol=val(id,l),nor=val(id,r),lal=val(v[p],l),lar=val(v[p],r);
    	if(nol>=lal&&nor>=lar)return;
    	if(nol<=lal&&nor<=lar)return v[p]=id,void();
    	db inter=1.*(li[id].se-li[v[p]].se)/(li[v[p]].fi-li[id].fi);
    	if(nol<=lal){
    		if(inter<=mid)update(id,l,mid,lc);
    		else update(v[p],mid+1,r,rc),v[p]=id;
    	}else{
    		if(inter>mid)update(id,mid+1,r,rc);
    		else update(v[p],l,mid,lc),v[p]=id;
    	}
    }
    LL query(int X,int l=1,int r=C,int p=1){
    	LL res=inf;
    	if(v[p])res=min(res,val(v[p],X));
    	if(l==r)return res;
    	int mid=(l+r)>>1;
    	if(X<=mid)res=min(res,query(X,l,mid,lc));
    	else res=min(res,query(X,mid+1,r,rc));
    	return res;
    }
    signed main(){
    	n=read();
    	for(int i=1;i<=n;++i)C=max(C,h[i]=read());
    	for(int i=1;i<=n;++i)w[i]=read(),s[i]=s[i-1]+w[i];
    	for(int i=1;i<=n;++i){
    		if(i==1)dp[i]=0;
    		else dp[i]=query(h[i])+1ll*h[i]*h[i]+s[i-1];
    		li[++cnt]=mkp(-2*h[i],dp[i]-s[i]+1ll*h[i]*h[i]);
    		update(cnt);
    	}
    	printf("%lld
    ",dp[n]);
    	return 0;
    }
    
    
  • 相关阅读:
    前后端反爬虫的一些奇怪姿势【转载】
    Scrapy 中常用的中间件和管道组件
    Jquery各个版本的区别
    userAgent
    操作系统
    手机类别
    移动端设备UA检测
    iPhone6的CSS3媒体查询
    所有设备的CSS像素
    解读所有设备的css像素的网站
  • 原文地址:https://www.cnblogs.com/zzctommy/p/13902441.html
Copyright © 2011-2022 走看看