#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();
while(q--)
{
int u,x;
cin>>u>>x;
cout<<ask(u,x)<<"\n";
}
return 0;
}
我先说一说我的思路:
首先构造一棵树,节点i的父节点就是往下第一个直径比它大的圆盘的编号。所以next[i]就表示第一个直径比第i个圆盘大的圆盘的编号,用单调栈解决即可。
然后我们递归这棵树,求出每个节点的深度。然后就可以初始化ST表,利用倍增解决问题。
所以为什么只有部分点AC?!