省选模拟12


T1

\(f_i\) 表示以 \(i\) 为结尾的答案,然后转移为 \(f_i=\max\limits_{j=1}^{i-1}(f_j+(a_i-a_j)^2+c)\)

这样会有不合法的情况无法转移,就是两个数之间有比他俩都大的值

但是这样的值一定会比从最大值转移要劣,所以直接斜率做一下就行

Code
#include
#define int long long
#define lson rt<<1
#define rson rt<<1|1
#define rint signed
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int n,C,ans;
int a[1000010],f[1000010];
inline int sq(int x){return x*x;}
struct node{
	int k,b;
	inline int calc(int x){return k*x+b;}
}st[1000010*4];
inline bool cover(node a,node b,int x){return b.calc(x)>=a.calc(x);}
void build(int rt,int l,int r){
	st[rt].k=0,st[rt].b=-inf;
	if(l==r) return ;
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
}
void ins(int rt,int l,int r,node k){
	if(cover(st[rt],k,l)&&cover(st[rt],k,r)) return st[rt]=k,void();
	if(l==r) return ;
	int mid=(l+r)>>1;
	if(cover(st[rt],k,mid)) swap(st[rt],k);
	if(cover(st[rt],k,l)) ins(lson,l,mid,k);
	if(cover(st[rt],k,r)) ins(rson,mid+1,r,k);
}
int query(int rt,int l,int r,int pos){
	if(l==r) return st[rt].calc(pos);
	int mid=(l+r)>>1,res=st[rt].calc(pos);
	if(pos<=mid) res=max(res,query(lson,l,mid,pos));
	else res=max(res,query(rson,mid+1,r,pos));
	return res;
}
signed main(){
#ifdef LOCAL
	freopen("in","r",stdin);
	freopen("out","w",stdout);
#endif
	freopen("array.in","r",stdin);
	freopen("array.out","w",stdout);
	n=read(),C=read();
	for(int i=1;i<=n;i++) a[i]=read();
	build(1,1,1000000);
	ins(1,1,1000000,(node){-2*a[1],f[1]+a[1]*a[1]});
	for(int i=2;i<=n;i++){
		f[i]=query(1,1,1000000,a[i])+C+a[i]*a[i];
		ins(1,1,1000000,(node){-2*a[i],f[i]+a[i]*a[i]});
	}
	printf("%lld\n",f[n]);
	return 0;
}

T2

先询问出全局的最大差值,然后二分一个位置找到任意一个极值的位置

因为每个数都不一样,于是与极值作差的结果也都不一样

再按二进制位拆分,每个差值都会在是二进制下是 \(1\) 的那一位出现一次

于是就能找出每个位置与极值的差,然后再找出最大的那个位置

询问一下,看看一开始的值是最大值还是最小值然后就能知道出所有数的值了

Code
#include "difference.h"
#include
using namespace std;
namespace TTT{
void find(int n, int M1, int M2){
	int pos,cpos,l,r,mx=-1,v,vc;
	vectorvec,s,c,anss;
	mapmp[20],t;
	vec.resize(n);c.resize(n);anss.resize(n);
	for(int i=0;i>1,tmx=-1;
		vec.resize(mid+1);for(int i=0;i<=mid;i++) vec[i]=i;
		s=qry2(vec);for(auto L:s) tmx=max(tmx,L);
		if(tmx==mx) r=mid-1,pos=mid;
		else l=mid+1;
	}
	for(int i=0;(1<>i&1;
		vec.clear();
		for(int j=1;j<=n;j++) if((j>>i)&1) if(j-1!=pos) vec.emplace_back(j-1);
		s=qry2(vec);for(auto L:s) mp[i][L]--;
		vec.clear();
		for(int j=1;j<=n;j++) if((j>>i)&1) if(j-1!=pos) vec.emplace_back(j-1);
		vec.emplace_back(pos);
		s=qry2(vec);for(auto L:s) mp[i][L]++;
	}
	for(int i=0,sum;i>j)&1){
			sum++;
			for(auto L:mp[j]) if(L.second!=0) t[L.first]++;
		}else for(auto L:mp[j]) if(L.second!=0) t[L.first]+=1000;
		for(auto L:t) if(L.second==sum) c[i]=L.first;
	}
	for(int i=0,tmx=-1;i

T3

咕咕咕