警示后人
查看原帖
警示后人
597716
IT__windy楼主2022/9/7 17:39

绝对不要用宏定义定义二分里的Clac()函数!!!

会爆精度!!!!

函数里一定要加 1ll*

因为这俩原因调了一下午
#include<bits/stdc++.h>
#define N 100005
#define ll unsigned long long
#define f1(i,n,m) for(int i=n;i<=m;++i)
#define f2(i,n,m) for(int i=n;i>=m;--i)
#define min(a,b) a<b? a:b
#define reset(a,b) memset(a,b,sizeof(a))
#define clac(i,j) (dp[j-1]+pow(sum[i]-sum[j]+1,2)*col[i])
#define s(i) (int)q[col[i]].size()-1
#define t1(i) q[col[i]][s(i)]
#define t2(i) q[col[i]][s(i)-1]
using namespace std;
template <typename T>
inline void read(T &x){
	int w=1;x=0;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	x*=w;
}
int n;
int col[N],pre[N],sum[N];
ll dp[N];
ll Clac(int i,int j) {return dp[j-1]+1ll*i*i*col[j];}
vector<int>q[N];
inline int bound(int x,int y){
	int mid,l=sum[y],r=n+1;
	while(l<r){
		mid=(l+r)>>1;
		Clac(mid-sum[x]+1,x)>=Clac(mid-sum[y]+1,y)?r=mid:l=mid+1;
	}
	return r;
}
signed main(){
	read(n);
	f1(i,1,n){
		read(col[i]);
		sum[i]=sum[pre[col[i]]]+1;
		pre[col[i]]=i;		
	}
	f1(i,1,n){
		while(s(i)>=1&&bound(t2(i),t1(i))<=bound(t1(i),i))q[col[i]].pop_back();
		q[col[i]].push_back(i);
		while(s(i)>=1&&clac(i,t2(i))>=clac(i,t1(i)))q[col[i]].pop_back();
		dp[i]=clac(i,t1(i));
//		cout<<t1(i)<<" ";
	}
	printf("%lld\n",dp[n]);
	return 0;
}
/*
10
2 2 30 2 2 2 30 2 2 2
*/
2022/9/7 17:39
加载中...