P7167 30pts 求调
查看原帖
P7167 30pts 求调
305925
Liu45318楼主2022/5/18 22:19

一直找不出错误,救救孩子。

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
const int MAXM=20;
const int INF=1e9+10;

int n,m,d[MAXN],c[MAXN];
int lg[MAXN],f[MAXN][MAXM];
stack<int> stk;
int g[MAXN][MAXM],h[MAXN][MAXM];

void input(){
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
		scanf("%d%d",&d[i],&c[i]);
}

void initLog(){
	lg[0]=-1;
	for (int i=1;i<=n;i++)
		if (!(i&i-1)) lg[i]=lg[i-1]+1;
		else lg[i]=lg[i-1];
}

void STcreate(){
	for (int i=1;i<=n;i++) f[i][0]=d[i];
	for (int j=1;j<=lg[n];j++)
		for (int i=1;i+(1<<j)-1<=n;i++)
			f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
	for (int i=n;i>=1;i--){
		while (!stk.empty()&&d[stk.top()]<=d[i]) stk.pop();
		if (stk.empty()){
			g[i][0]=0;h[i][0]=INF; 
		}else{
			g[i][0]=stk.top();h[i][0]=c[stk.top()];
		}
		stk.push(i);
	}
	for (int j=1;j<=lg[n];j++)
		for (int i=1;i+(1<<j)<=n;i++){
			g[i][j]=g[g[i][j-1]][j-1];
			h[i][j]=h[i][j-1]+h[g[i][j-1]][j-1];
		}
}

void solve(){
	while (m--){
		int r,v;
		scanf("%d%d",&r,&v);v-=c[r];
		for (int j=lg[n-r]+1;j>=0;j--)
			if (h[r][j]>0&&h[r][j]<=v){
				v-=h[r][j];
				r=g[r][j];
			}
		if (v>0) printf("%d\n",g[r][0]);
		else printf("%d\n",r);
	}
}

int main(){
	input();
	initLog();
	STcreate();
	solve();
	return 0;
}
2022/5/18 22:19
加载中...