zoukankan      html  css  js  c++  java
  • P4983 忘情

    这题真的很裸吧,就是一个更为简单的( ext{wqs})二分然后斜率优化。

    题目里的式子稍加推导发现就是((sum+1)^2),斜率优化即可。

    注意这里斜率比较不能用乘法,因为会爆( ext{long long}),然后二分的边界要开大一点。

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int maxn=2e5+10;
    const int mod=1e9+7;
    int n,m,a[maxn],sum[maxn],f[maxn],num[maxn],q[maxn];
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    	return x*f;
    }
    inline int yval(int x){return f[x]+sum[x]*sum[x]-2*sum[x];}
    inline int dx(int x,int y){return sum[y]-sum[x];}
    inline int dy(int x,int y){return yval(y)-yval(x);}
    inline double slope(int x,int y){return 1.0*dy(x,y)/dx(x,y);}
    inline void calc(int val){
    	int l,r;q[l=r=1]=0;
    	for(int i=1;i<=n;i++){
    		while(l<r&&slope(q[l],q[l+1])<=2*sum[i])l++;
    		f[i]=f[q[l]]+(sum[i]-sum[q[l]]+1)*(sum[i]-sum[q[l]]+1)+val;
    		num[i]=num[q[l]]+1;
    		while(l<r&&slope(q[r],i)<=slope(q[r-1],q[r]))r--;
    		q[++r]=i;
    	}
    }
    signed main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++)a[i]=read();
    	for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
    	int l=0,r=1e18;
    	for(int i=1;i<=100;i++){
    		int mid=(l+r)>>1;
    		calc(mid);
    		if(num[n]>m)l=mid;
    		else r=mid;
    	}
    	calc(l);
    	printf("%lld
    ",f[n]-l*m);
    	return 0;
    }
    
  • 相关阅读:
    Python类的继承(进阶5)
    面向对象编程基础(进阶4)
    Python模块(进阶3)
    Python函数式编程(进阶2)
    python多线程
    Ternary Search Tree Java实现
    Trie和Ternary Search Tree介绍
    索引时利用K-邻近算法过滤重复歌曲
    Sql排名和分组排名
    Lucene和jackson冲突
  • 原文地址:https://www.cnblogs.com/syzf2222/p/14411763.html
Copyright © 2011-2022 走看看