思路是对的,样例是过的,为什么是错的,求助!
查看原帖
思路是对的,样例是过的,为什么是错的,求助!
1471260
guoshengyu1231楼主2024/12/21 14:56
#include<iostream>
#include<vector>
#include<cmath>
#include<stack>
using namespace std;
const int maxn=1e5+5;
int n,q,maxd,k;
struct tree{
	int v,w;
}next[maxn],ST[maxn][30];
int a[maxn],deep[maxn];
stack<int> s;
vector<int> g[maxn];//邻接表 
void dfs(int root,int d)
{
	deep[root]=d;
	maxd=max(maxd,d);
	for(int i=0;i<g[root].size();i++)
	 dfs(g[root][i],d+1);
} 
int ask(int u,int x)
{
	int k=log2(deep[u]);
	for(int i=k;i>=0;i--)
	 if(x>ST[u][i].w)
	  {
		x-=ST[u][i].w;
		u=ST[u][i].v;
		if(u==0) return 0;
	  }
	return u;
}
void init_ST()
{
	for(int i=1;i<=n;i++)
	 ST[i][0]=next[i];
	for(int j=1;j<=k;j++)
	 for(int i=1;i<=n;i++)
	  {
		if(deep[i]<1<<j) continue;
		ST[i][j].v=ST[ST[i][j-1].v][j-1].v;
		ST[i][j].w=ST[i][j-1].w+ST[ST[i][j-1].v][j-1].w;
	  }
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);//输入输出优化 
	cin>>n>>q;
	for(int i=1;i<=n;i++) cin>>a[i]>>next[i].w;
	for(int i=1;i<=n;i++)
	 {
		while(!s.empty()&&a[i]>a[s.top()])	
		 {
			next[s.top()].v=i;
			s.pop();
		 }
		s.push(i);
	 }//单调栈求最值 
	for(int i=1;i<=n;i++)
	 g[next[i].v].push_back(i);
	dfs(0,0);//求每个节点的深度 
	k=log2(maxd);
	init_ST();//初始化ST表 
	while(q--)
	 {
		int u,x;
		cin>>u>>x;
		cout<<ask(u,x)<<"\n";
	 }
	return 0;
}

我先说一说我的思路:

首先构造一棵树,节点i的父节点就是往下第一个直径比它大的圆盘的编号。所以next[i]就表示第一个直径比第i个圆盘大的圆盘的编号,用单调栈解决即可。

然后我们递归这棵树,求出每个节点的深度。然后就可以初始化ST表,利用倍增解决问题。

所以为什么只有部分点AC?!

2024/12/21 14:56
加载中...