玄关求调,斜优WA20pts
查看原帖
玄关求调,斜优WA20pts
552454
洛苡hh楼主2025/6/18 14:18

维护了一个上凸壳

#include<bits/stdc++.h>
#define MAXN 200005
#define MAXM 1005
#define int long long
#define look_memory cerr<<abs(&M2-&M1)/1024.0/1024<<'\n'
#define look_time cerr<<(clock()-Time)*1.0/CLOCKS_PER_SEC<<'\n'
using namespace std;

inline int read(){
    int x=0;
    int f=1;
    char c=getchar();
    while(c<'0' || c>'9'){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0' && c<='9'){
        x=(x<<1)+(x<<3)+(c^48);
		c=getchar();
	}
	return x*f;
}

bool M1;
int n,m;
struct node{
	int x,y;
};
int w[MAXM][MAXM];
deque<node> q;
int pos[MAXM],dis[MAXM],f[MAXM][MAXM];
const int inf=1e9;
const double eps=1e-6;

double get_k(node aa,node bb){
	return 1.0*(bb.y-aa.y)/((aa.x==bb.x)?eps:(bb.x-aa.x));
}

bool M2;

signed main(){
//  freopen("","r",stdin);
//  freopen("","w",stdout);
    int Time=clock();
	n=read();m=read();
	for(int i=1;i<=n;i++){
		int x,y;
		x=read();y=read();
		w[x][y]=read();
	}
	memset(f,-0x3f,sizeof(f));
	f[1][1]=w[1][1];
	pos[1]=1;
	for(int i=1;i<=m;i++){
		q.clear();
		for(int j=1;j<=m;j++){
			if(pos[j]) dis[j]=(i-pos[j])*(i-pos[j]);
			else dis[j]=0;
		}
		for(int j=1;j<=m;j++){
			if(pos[j]){
				node tmp={j,f[pos[j]][j]-dis[j]-j*j};
				while(q.size()>=2 && get_k(q[q.size()-2],tmp)>=get_k(q[q.size()-2],q.back())) q.pop_back();
				q.push_back(tmp);
			}
			if(w[i][j] && (i>1&&j>1)){
				while(q.size()>=2 && -2*j<=get_k(q[0],q[1])) q.pop_front();
				int x=q.front().x,y=q.front().y;
//				printf("i=%d j=%d x=%d\n",i,j,x);
				f[i][j]=w[i][j]-j*j+2*j*x+y;
				pos[j]=i;
				dis[j]=0;
				node tmp={j,f[pos[j]][j]-dis[j]-j*j};
				while(q.size()>=2 && get_k(q[q.size()-2],tmp)>=get_k(q[q.size()-2],q.back())) q.pop_back();
				q.push_back(tmp);
			}
		}
	}
	int ans=f[m][m];
	printf("%lld\n",ans);
    look_memory;
    look_time;
    return 0;
}
2025/6/18 14:18
加载中...