全RE 求助大佬
查看原帖
全RE 求助大佬
614725
masonpop楼主2022/6/11 12:58

RE???

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,H[maxn],X,m;//一些数组
int f[maxn][20],p[maxn][20],q[maxn][20];//倍增数组,跳2^j轮 
int A[maxn],B[maxn];//a从i开始到哪里,B同理 
void init()//初始化倍增数组,A,B等 
{
	int tot=0;
	set< pair<int,int> > s;//表示<H[i],i>
	pair<int,pair<int,int> > tmp[5];//第一个为海拔差,后面是s的pair
	for(int i=n;i>=1;i--)//注意方向 
	{
		s.insert(make_pair(H[i],i));//插入这个城市
		set<pair<int,int> >::iterator pre,suc;//前驱,后继
		pre=suc=s.lower_bound(make_pair(H[i],i));//找到自己的地址
		if(pre!=s.begin())//不是最小的 
		{
			tmp[++tot].second=*(--pre);//前一个 
			if(pre!=s.begin())
			{
				tmp[++tot].second=*(--pre);//再前一个 
			}
		} 
		if((++suc)!=s.end())//不是最大的 
		{
			tmp[++tot].second=*suc;//前一个 
			if((++suc)!=s.end())
			{
				tmp[++tot].second=*suc;//再前一个 
			}
		} 
		for(int j=1;j<=tot;j++)
		{
			tmp[j].first=abs(H[i]-tmp[j].second.first);//计算距离 
		}
		sort(tmp+1,tmp+tot+1);//排序
		if(tot>=1)B[i]=tmp[1].second.second;//存储
		if(tot>=2)A[i]=tmp[2].second.second; 
		f[i][0]=B[A[i]];//初始化倍增数组 
	} 
}
pair<int,int> query(int x,int y)//从x开始,最多y 
{
	int cnta=0,cntb=0;//记录路程
	for(int j=16;j>=0;j--)//倍增计算
	{
		if(f[x][j] && (p[x][j]+q[x][j]<=y))//可以跳跃
		{
			y-=(p[x][j]+q[x][j]);
			cnta+=p[x][j];
			cntb+=q[x][j];//累加 
			x=f[x][j];//跳跃 
		} 
	} 
	if(p[x][0]<=y)//a跳最后一下
	{
		y-=p[x][0];
		cnta+=p[x][0];//累加 
	} 
	return make_pair(cnta,cntb);
} 
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&H[i]);
	scanf("%d",&X);
	scanf("%d",&m);//各种输入 
	init();//初始化 
	for(int i=0;i<=n;i++)
	{
		for(int j=0;j<=16;j++)
		{
			p[i][j]=f[i][j]=1e9;//无穷大 
		}
	}
	for(int i=1;i<=n;i++)
	{
		if(A[i])p[i][0]=abs(H[i]-H[A[i]]);//初始化
		if(B[A[i]])q[i][0]=abs(H[A[i]]-H[B[A[i]]]);//注意嵌套 
	}
	for(int j=1;j<=16;j++)//倍增 
	{
		for(int i=1;i<=n;i++)
		{
			f[i][j]=f[f[i][j-1]][j-1];//倍增数组递推
			p[i][j]=p[i][j-1]+p[f[i][j-1]][j-1];//分段 
			q[i][j]=q[i][j-1]+q[f[i][j-1]][j-1];//同理 
		}
	}
	int x,y;
	pair<int,int> tmp,ans;//解决询问,分别表示a,b路程 
	ans=make_pair(1,0);//1/0,即inf
	int pos=0;
	for(int i=1;i<=n;i++)
	{
		tmp=query(i,X);//计算
		if((1LL*tmp.first*ans.second) < (1LL*tmp.second*ans.first))//十字相乘,避免/0
		{
			ans=tmp;
			pos=i;//存储 
		} 
	} 
	printf("%d\n",pos);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);//输入
		tmp=query(x,y);
		printf("%d %d\n",tmp.first,tmp.second);//输出 
	}
	return 0;
}
2022/6/11 12:58
加载中...