0pts悬关求助
查看原帖
0pts悬关求助
349824
WsW_花逝爆零人楼主2024/8/2 14:39

树上倍增,选定 n+1n+1 为 00 号盘子。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long ull;
const int MAXN=1e5+5;
int n,q;
int d[MAXN],c[MAXN];
stack<int>s;
int f[MAXN][20];
int sum[MAXN][20];
int dep[MAXN];
int lg[MAXN];
vector<int>edg[MAXN];
void dfs(int p,int fa){
	dep[p]=dep[fa]+1;
	f[p][0]=fa;
	sum[p][0]=c[p];
	for(int i=1;i<=lg[dep[p]];i++){
		f[p][i]=f[f[p][i-1]][i-1];
		sum[p][i]=sum[f[p][i-1]][i-1]+sum[p][i-1];
	}
	for(int i=0;i<edg[p].size();i++)dfs(edg[p][i],p);
}

int query(int r,int v){
	for(int i=lg[dep[r]];i>=0;i--){
		if(v<=sum[r][i])continue;
		v-=sum[r][i];
		r=f[r][i];
	}
	if(r==n)return 0;
	return r;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>q;
	lg[0]=-1; n++;
	for(int i=1;i<=n;i++){
		lg[i]=lg[i>>1]+1;
		if(i<n)cin>>d[i]>>c[i];
		else d[i]=c[i]=2e9;
		while(!s.empty()&&d[s.top()]<d[i]){
			edg[i].push_back(s.top());
			s.pop();
		}
		s.push(i);
	}
	dfs(n,0);
	while(q--){
		int r,v;
		cin>>r>>v;
		cout<<query(r,v)<<'\n';
	}
	return 0;
}
2024/8/2 14:39
加载中...