关于动态开点线段树
查看原帖
关于动态开点线段树
151712
一架飞机楼主2021/3/21 12:20

这道题应该可以用动态开点线段树的吧。为什么会RE呢?70分提交记录

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
template <typename T>inline void read(T&x){
	x=0; char temp=getchar(); bool f=false;
	while(!isdigit(temp)){if(temp=='-') f=true; temp=getchar();}
	while(isdigit(temp)){x=(x<<1)+(x<<3)+temp-'0'; temp=getchar();}
	if(f) x=-x;
}
template <typename T>void print(T x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) print(x/10);
	putchar(x%10+'0');
}
const int M=5e5+5;
int val[M*29],lch[M*29],rch[M*29],tot;
void insert(int &p,int L,int R,int d,int x){//cout<<L<<' '<<R<<endl;
	if(!p)p=++tot;
	if(L==R){val[p]=x;return;}
	int mid=(L+R)>>1;
	if(d<=mid)insert(lch[p],L,mid,d,x);
	else insert(rch[p],mid+1,R,d,x);
	val[p]=max(val[lch[p]],val[rch[p]]);
}
int ask(int &p,int L,int R,int l,int r){//cout<<L<<' '<<R<<endl;
	if(!p||l>R||r<L||l>r)return -1e9-9;
	if(l<=L&&R<=r)return val[p];
	int mid=(L+R)>>1;
	return max(ask(lch[p],L,mid,l,r),ask(rch[p],mid+1,R,l,r));
}
int a[M],b[M],n,d,K,rt,RR;
bool check(int g){
	memset(val,0xcf,sizeof(val));
	memset(lch,0,sizeof(lch));
	memset(rch,0,sizeof(rch));
	rt=0;tot=0;insert(rt,0,RR,0,0);
	for(int ii=1;ii<=n;ii++){
		int i=a[ii];
		int k=ask(rt,0,RR,max(0,i-(d+g)),i-max(1,d-g))+b[ii];
		if(k>=K)return 1;
		insert(rt,0,RR,i,k);
	}
	return 0;
}
int main(){
	cin>>n>>d>>K;
	for(int i=1;i<=n;i++)cin>>a[i]>>b[i],RR=max(a[i],RR);
	int l=0,r=RR,ans=-1;
	while(l<=r){
		int mid=(l+r)>>1;
		if(check(mid))r=mid-1,ans=mid;
		else l=mid+1;
	}
	cout<<ans;
	return 0;
}
2021/3/21 12:20
加载中...