zoukankan      html  css  js  c++  java
  • 20211005省选组T1 数列(array)

    链接

    考虑对于一个点,能转移来的只有一条单调下降的序列和一条单调上升的序列。

    那么我们直接用单调栈维护这两个,同时发现转移的形式是跟斜率优化类似的,套用斜率优化即可,对于一个序列在同一个单调栈上维护 (a_i) 的单调和斜率的单调。

    注意两条链使用斜率优化时的符号不一样。

    #include<bits/stdc++.h>
    #define fo(i,a,b) for(int i=a;i<=b;++i)
    #define fd(i,a,b) for(int i=a;i>=b;--i)
    #define ll __int128
    #define db double
    using namespace std;
    const int N=1e6+10;
    int n,m,a[N],la[N],q1[N],q2[N],r1,r2;
    ll f[N],ans;
    int b[N],tot=0;
    ll sqr(ll a){return a*a;}
    void write(ll ans){
    	while(ans){
    		b[tot++]=ans%10;
    		ans/=10;
    	}
    	fd(i,tot-1,0)printf("%d",b[i]);
    }
    db calc(int x,int y){
    	return (db)(f[x]-f[y] + sqr(a[x]) - sqr(a[y])) / (db)(a[x]-a[y]) / 2;
    }
    int main(){
    	freopen("array.in","r",stdin);
    	freopen("array.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	fo(i,1,n)scanf("%d",&a[i]);
    	r1=r2=1;
    	q1[1]=q2[1]=1;
    	fo(i,2,n){
    		while(r1>1 && calc(q1[r1-1],q1[r1])>a[i])--r1;
    		while(r2>1 && calc(q2[r2-1],q2[r2])<a[i])--r2;
    		int t=q1[r1];
    		f[i]=f[t] + m + sqr(a[i] - a[t]);
    		t=q2[r2];
    		f[i]=max(f[i],f[t] + m + sqr(a[i] - a[t]));
    		ans=max(ans,f[i]);
    		while(r1 && a[q1[r1]]<=a[i])--r1;
    		while(r2 && a[q2[r2]]>=a[i])--r2;
    		while(r1>1 && calc(q1[r1-1],q1[r1])>=calc(q1[r1],i))--r1;
    		while(r2>1 && calc(q2[r2-1],q2[r2])<=calc(q2[r2],i))--r2;
    		q1[++r1]=q2[++r2]=i;
    	}
    	write(ans);
    
    	return 0;
    }
    
  • 相关阅读:
    Eclipse插件安装方法大全
    Weblogic web应用中获取文件的绝对路径
    Weblogic 设置优先引用web项目的jar包
    Oracle 数据库创建(图形界面操作)
    Java 输入输出流总结
    如何获取项目中文件的路径
    EclEmma安装与使用
    单向链表

    散列表
  • 原文地址:https://www.cnblogs.com/Kelvin2005/p/15368971.html
Copyright © 2011-2022 走看看