两个点TLE,求条
查看原帖
两个点TLE,求条
1340759
ARIS2_0楼主2024/10/29 15:59

rt。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+10,maxlog=log2(maxn)+10;
int n,q;
int r[maxn],v[maxn],log_2[maxn];
void init(){//O(n)
	for(int i=1;i<=n;i++){
		cin>>r[i]>>v[i];
	}
	n++;
	r[n]=9e18;
	v[n]=9e18;
	log_2[1]=0;
	for(int i=2;i<maxn;i++){
		log_2[i]=log_2[i>>1]+1;
	}
}
int nxt[maxn],st[maxn][maxlog];
//st[i][j]为r[i]-r[i+(1<<j)-1]的max 
void yclst(){//O(nlogn)
	for(int i=1;i<=n;i++){
		st[i][0]=r[i];
	}
	for(int j=1;;j++){
		bool have=0;
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n){
				break;
			}
			have=1;
			st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		}
		if(!have){
			break;
		}
	}
}
int checkmax(int l,int r){//O(1)
	int p=log_2[r-l+1];
	return max(st[l][p],st[r-(1<<p)+1][p]);
}
void yclnxt(){//O(nlogn)
	yclst();//O(nlogn)
	for(int i=1;i<=n;i++){
		int le=i+1,re=n;
		int ans=0;
		while(le<=re){
			int mid=(le+re)/2;
			if(checkmax(i+1,mid)>r[i]){
				ans=mid;re=mid-1;
			}
			else le=mid+1;
		}
		nxt[i]=ans;
//		if(nxt[i]==i){
//			cout<<r[357325953653745335];
//		}
	}
}
int id[maxn][maxlog],sum[maxn][maxlog],maxjump[maxn];
bool okay[maxn][maxlog];
void ycl(){//O(nlogn)
	yclnxt();//O(nlogn)
	//ycl:id[i][j],sum[i][j];
//	memset(sum,0x3f,sizeof(sum));
	for(int i=1;i<=n;i++){
		id[i][0]=nxt[i];
		sum[i][0]=v[nxt[i]];
		maxjump[i]=0;
	}
	for(int j=1;;j++){
//		cout<<"ihisfsf\n";
		bool have=0;
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1>n){
				break;
			}
			id[i][j]=id[id[i][j-1]][j-1];
			if(id[i][j]==0 or id[i][j-1]==0){
				break;
			}
			have=1;
//			if(id[i][j]==i){
//				cout<<r[9384578936739673];
//			}
			sum[i][j]=sum[i][j-1]+sum[id[i][j-1]][j-1];
			maxjump[i]=j;
		}
		if(!have){
			break;
		}
	}
}
int check(int lakeid,int water){//O(logn*logn)
	//id[i][j]为i跳(1<<j)次的id
	//sum[i][j]为i跳(1<<j)次时能承载的最大水量(不含第i个盘子) 
	if(water<=v[lakeid]){
		return lakeid;
	}
	water-=v[lakeid];
	int ans=0;
//	vector<int>aa;
	while(1){
		int pos=lower_bound(sum[lakeid],sum[lakeid]+maxjump[lakeid]+1,water-ans)-sum[lakeid]-1;
		if(pos==-1){
			break;
		}
		ans+=sum[lakeid][pos];
//		if(water-ans<0){
//			while(1){
//				aa.push_back(234252);
//			}
//		}
//		if(lakeid>=n){
//			cout<<r[892748467298472];
//		}
		lakeid=id[lakeid][pos];
//		aa.push_back(213424);
	}
	if(nxt[lakeid]==n){
		return 0;
	}
	return nxt[lakeid];
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>q;
//	n=100000;
	init();//O(n)
	ycl();//O(nlogn)
	while(q--){//O(logn*logn*q)
		int pt,qt;cin>>pt>>qt;
		cout<<check(pt,qt)<<"\n";
	}
//	cout<<maxn*log_2[maxn-1]+maxn*log_2[maxn-1]*log_2[maxn-1];
	return 0;
}
//O(nlogn+q*logn*logn)

蒟蒻做了一下午,救救蒟蒻吧qwq

2024/10/29 15:59
加载中...