-->

[Noip2019]划分

2020-08-15 15:06发布

[Noip2019]划分

一.前言

​ 没保存哭了……重写。呕这该死的高精度,dev-c++,lemon,int128,O2,给我人都整傻了。本文不带高精度喔。,题目链接

二.思路

​ 首先我们可以找到一些奇奇怪怪的dp,这之中较为突出的是 \(f[i][j]=min\{f[k][j]+(sum[i]-sum[j])^2\}\).但是!我们先不管他好吧。

​ 根据和平方大于平方和的基本不等式来看,我们追求划分的段尽量多。而题目又有一个划分的每一段的和不下降的条件,很容易能想到最后一段越小,能划的段就越多(因为所有总和一定,都是段和)。于是乎我们每次追求转移的时候\((sum[i]-sum[j])^2\)的值最小,然后划掉平方,也就是使得段和最小。

​ 由于前缀和不降,所以 j 尽量靠近 i (要大要小很难办w)(设段和为 \(sig\) )希望在 \(sum[i]-sum[j]>=sig[j]\) 的前提之下 j 尽量大,移项使得 \(sum[i]>=sig[j]+sum[j]\) 于是维护一个单调上升的队列就行。

三.CODE

#include <cstdio>
#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define m_for(i,a,b) for(int i=a;i<=b;++i)
int read(){
	char ch=getchar();
	int res=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())res=res*10+(ch-'0');
	return res*f;
}
const int MAXN=4*1e7;
int n,type,a[MAXN],dd[MAXN],head,tail,pre[MAXN];
long long sum[MAXN],sig[MAXN];
long long x,y,z,b[4],m;
void pt(__int128 a){
    static int st[55];
    while(a){
        st[++st[0]]=a%10;
        a/=10;
    }
    while(st[0])printf("%d",st[st[0]--]);
}
int main(){
	n=read();type=read();
	if(!type)m_for(i,1,n)a[i]=read();
	else{
		x=read();
		y=read();
		z=read();
		b[1]=read();
		b[2]=read();
		m=read();
		for(int i=1,last=0,p,l,r;i<=m;++i)
		{
			p=read();
			l=read();
			r=read();
			for(int j=last+1;j<=p;++j)
			{
				if(j>2)
				{
					b[3]=((long long)x*b[2]+(long long)y*b[1]+z)&((1 << 30) - 1);
					b[1]=b[2];
					b[2]=b[3];
					a[j]=b[3]%(r-l+1)+l;
				}	
				else a[j]=b[j]%(r-l+1)+l;
			}
			last=p;
		}
	}
	m_for(i,1,n)sum[i]=sum[i-1]+1LL*a[i];
	m_for(i,1,n){
		while(head<tail&&sig[dd[head+1]]+sum[dd[head+1]]<=sum[i])++head;
		sig[i]=sum[i]-sum[dd[head]];
		pre[i]=dd[head];
		while(head<tail&&sig[dd[tail]]+sum[dd[tail]]>=sig[i]+sum[i])--tail;
		dd[++tail]=i;
	}
	__int128 ans=0LL;
	int now=n;
	while(now){
		ans+=__int128(sig[now])*sig[now];
		now=pre[now];
	}
	pt(ans);
	return 0;
}

我无论是手写高精还是__int128 都用不起,只有 88 分,就酱。

标签: