卡 95 分,第八个点错误,求助
查看原帖
卡 95 分,第八个点错误,求助
128591
Refined_heart楼主2021/7/25 13:35

正确输出: 12869469,6313758

我的输出: 12805982 6369739

求问原因,调了好久也不知道为啥

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN=1e5+10;
const int inf=(1LL<<60);
int n,h[MAXN],s[MAXN],x[MAXN],m;
int ga[MAXN],gb[MAXN],f[20][MAXN][2];
int da[20][MAXN][2],db[20][MAXN][2];
const double eps=1e-14;
map<int,int>mp;
inline int Min(int x,int y){return x<y?x:y;}
inline int Max(int x,int y){return x>y?x:y;}
inline int Abs(int x){if(x<0)x=-x;return x;}
inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		s=s*10-48+ch;
		ch=getchar();
	}
	return s*w;
}
set<int> S,T;
void pretreatment(){
	n=read();
	for(int i=1;i<=n;++i)h[i]=read();
	for(int i=1;i<=n;++i)mp[h[i]]=i;
	x[0]=read();m=read();
	for(int i=1;i<=m;++i)s[i]=read(),x[i]=read();
	for(int i=n;i>=1;--i){
		if(S.empty()){
			ga[i]=gb[i]=-1;
			S.insert(h[i]);
			T.insert(-h[i]);
			continue;
		}
		set<int>::iterator preit=S.lower_bound(h[i]);
		set<int>::iterator sufit=T.lower_bound(-h[i]);
		int preb,sufb;
		if(preit==S.end())preb=inf;
		else preb=*(preit);
		if(sufit==T.end())sufb=inf;
		else sufb=-(*(sufit));
		if(preb==sufb&&preb==inf){
			ga[i]=gb[i]-1;
			S.insert(h[i]);
			T.insert(-h[i]);
			continue;
		}
		swap(preb,sufb);
		if(Abs(preb-h[i])<Abs(sufb-h[i]))gb[i]=mp[preb];
		else if(Abs(sufb-h[i])<Abs(preb-h[i]))gb[i]=mp[sufb];
		else gb[i]=mp[preb];
		swap(preb,sufb);
		int p_preb;
		int s_sufb;
		if(preb!=inf)S.erase(preb);
		if(sufb!=inf)T.erase(-sufb);
		if(preb!=inf)preit=S.lower_bound(preb);
		else preit=S.end();
		if(sufb!=inf)sufit=T.lower_bound(-sufb);
		else sufit=T.end();
		if(preit==S.end()||preb==inf)p_preb=inf;
		else p_preb=*(preit);
		if(sufit==T.end()||sufb==inf)s_sufb=inf;
		else s_sufb=-(*(sufit));
		if(preb!=inf)S.insert(preb);
		if(sufb!=inf)T.insert(-sufb);
		int cnt=0;
		if(preb==inf)cnt++;
		if(sufb==inf)cnt++;
		if(p_preb==inf)cnt++;
		if(s_sufb==inf)cnt++;
		if(cnt>=3){
			ga[i]=-1;
			S.insert(h[i]);
			T.insert(-h[i]);
			continue;
		}
		swap(p_preb,s_sufb);
		int t[4];
		t [ 0 ] = sufb ; t [ 1 ] = preb ;
		t [ 2 ] = s_sufb ; t [ 3 ] = p_preb ;
		int mi=inf,cmi=inf;
		for(int j=3;~j;--j){
			if(Abs(t[j]-h[i])<=Abs(mi-h[i])){
				cmi=mi;
				mi=t[j];
			}
			else if(Abs(t[j]-h[i])<=Abs(cmi-h[i])){
				cmi=t[j];
			}
		}
		ga[i]=mp[cmi];
		S.insert(h[i]);
		T.insert(-h[i]);
	}
	for(int i=0;i<20;++i)
		for(int j=0;j<=n;++j)
			f[i][j][0]=f[i][j][1]=-inf,
			da[i][j][0]=da[i][j][1]=-inf,
			db[i][j][0]=db[i][j][1]=-inf;
	for(int i=1;i<=n;++i){
		f[0][i][0]=ga[i];
		f[0][i][1]=gb[i];
		if(ga[i]!=-1)da[0][i][0]=Abs(h[ga[i]]-h[i]);
		else da[0][i][0]=-inf;
		da[0][i][1]=0;
		db[0][i][0]=0;
		if(gb[i]!=-1)db[0][i][1]=Abs(h[gb[i]]-h[i]);
		else db[0][i][1]=-inf;
	}
	for(int i=1;i<=n;++i){
		if(f[0][i][0]>=0){
			f[1][i][0]=f[0][f[0][i][0]][1];	
			da[1][i][0]=da[0][i][0]+da[0][f[0][i][0]][1];
			db[1][i][0]=db[0][i][0]+db[0][f[0][i][0]][1];
		}
		else {
			da[1][i][0]=-inf;
			db[1][i][0]=-inf;
			f[1][i][0]=-inf;	
		}
		if(f[0][i][1]>=0){
			f[1][i][1]=f[0][f[0][i][1]][0];
			da[1][i][1]=da[0][i][1]+da[0][f[0][i][1]][0];
			db[1][i][1]=db[0][i][1]+db[0][f[0][i][1]][0];
		}
		else{
			da[1][i][1]=-inf;
			db[1][i][1]=-inf;
			f[1][i][1]=-inf;
		}
	}
	for(int i=2;i<20;++i){
		for(int j=1;j<=n;++j){
			if(f[i-1][j][0]>=0)f[i][j][0]=f[i-1][f[i-1][j][0]][0];
			if(f[i-1][j][1]>=0)f[i][j][1]=f[i-1][f[i-1][j][1]][1];
			if(f[i-1][j][0]>=0)da[i][j][0]=da[i-1][j][0]+da[i-1][f[i-1][j][0]][0];
			if(f[i-1][j][1]>=0)da[i][j][1]=da[i-1][j][1]+da[i-1][f[i-1][j][1]][1];
			if(f[i-1][j][0]>=0)db[i][j][0]=db[i-1][j][0]+db[i-1][f[i-1][j][0]][0];
			if(f[i-1][j][1]>=0)db[i][j][1]=db[i-1][j][1]+db[i-1][f[i-1][j][1]][1];
		}
	}
}
pair<int,int> calc(int S,int dis){
	int disa=0,disb=0;
	for(int i=19;~i;--i){
		if(f[i][S][0]<0)continue;
		if(disa+disb+da[i][S][0]+db[i][S][0]<=dis){
			disa+=da[i][S][0];
			disb+=db[i][S][0];
			S=f[i][S][0];
		}
	}
	return make_pair(disa,disb);
}
inline bool check(double x,double y){
	if(x-y>eps)return true;
	return false;
}
inline bool ck(double x,double y){
	if(fabs(x-y)<=eps)return true;
	return false;
}
void solve(){
	double ratio=200000000000.1;
	int pos=-1;
	for(int i=1;i<=n;++i){
		pair<int,int> pr=calc(i,x[0]);
		double rto=0.0;
		if(pr.first==0&&pr.second==0){
			rto=2000000000000.1;
		}
		else if(pr.first==0&&pr.second!=0){
			rto=0.0;
		}
		else if(pr.first!=0&&pr.second==0){
			rto=2000000000000.1;
		}
		else rto=(double)(pr.first)/(double)(pr.second);
		if(pos==-1){
			pos=i;
			ratio=rto;
			continue;
		}
		if(check(ratio,rto)){
			ratio=rto;
			pos=i;
		}
		else if(ck(ratio,rto)&&h[i]>h[pos]){
			pos=i;
		}
	}
	printf("%lld\n",pos);
	for(int i=1;i<=m;++i){
		pair<int,int> pr=calc(s[i],x[i]);
		printf("%lld %lld\n",pr.first,pr.second);
	}
}
signed main(){
	pretreatment();
	solve();
	return 0;
}
2021/7/25 13:35
加载中...