首页 > 其他分享 >[APIO2010] 特别行动队

[APIO2010] 特别行动队

时间:2022-11-05 10:58:00浏览次数:72  
标签:特别 ch int APIO2010 pair 行动队 include define

Statement

传送门

Solution

先考虑最暴力的\(dp\),也就是\(f_i=\max_{j=0}^if_j+a(s_i-s_j)^2+b(s_i-s_j)+c\),其中\(s_i\)表示\(x_i\)的前缀和.

那么此时我们可以把式子拆开,不难发现是要我们维护一个上凸包然后取队首即可.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define re register
#define ll long long
#define int ll
#define mp make_pair
#define sqr(x) ((x)*(x))
typedef pair<int,int> pii;
inline int gi(){
    int f=1,sum=0;char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return sum*f;
}
const int N=1000010;
int n,q[N],a,b,c,x[N],s[N],f[N];
int calc(int i,int j){return f[j]+a*sqr(s[i]-s[j])+b*(s[i]-s[j])+c;}
double slope(int i,int j){
    int x=s[j],y=f[j]+a*s[j]*s[j]-b*s[j];
    int X=s[i],Y=f[i]+a*s[i]*s[i]-b*s[i];
    return (double)1.*(Y-y)/(X-x);
}
signed main(){
#ifndef ONLINE_JUDGE
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
#endif
    n=gi();
    a=gi();b=gi();c=gi();
    for(int i=1;i<=n;i++)x[i]=gi(),s[i]=s[i-1]+x[i];
    int h,t;q[h=t=1]=0;
    for(int i=1;i<=n;i++){
        while(h<t&&calc(i,q[h])<calc(i,q[h+1]))h++;
        f[i]=calc(i,q[h]);
        while(h<t&&slope(q[t],i)>=slope(q[t-1],q[t]))t--;
        q[++t]=i;
    }
    printf("%lld\n",f[n]);
    return 0;
}

标签:特别,ch,int,APIO2010,pair,行动队,include,define
From: https://www.cnblogs.com/WhiteSmile/p/16859766.html

相关文章