给写树套树的冤种们的一点改进思路
  • 板块CF19D Points
  • 楼主K2Cr2O7
  • 当前回复5
  • 已保存回复5
  • 发布时间2024/1/11 19:10
  • 上次更新2024/1/11 22:00:52
查看原帖
给写树套树的冤种们的一点改进思路
361965
K2Cr2O7楼主2024/1/11 19:10

每个线段树节点不用开 set,直接存最大的 y 坐标就好了,足够二分的时候用了,只有底层节点才需要开 set。

这样一来,代码的复杂度虽然是两个 log 的,但是能过。

然后写出来的代码可能是这样的。

#include<bits/stdc++.h>
using namespace std;
const int maxn=200004;
char op[maxn<<2];
int n,recx[maxn],recy[maxn],mpx[maxn*2],mpy[maxn*2],maxy[maxn<<3];
vector< int > cpy;
set< int > mem[maxn<<3];

void add(int l,int r,int ver,int x,int y){
	if(l==r){
		mem[ver].insert(y);
		maxy[ver]=max(maxy[ver],y);
		return ;
	}
	int mid=(l+r)>>1,lver=ver<<1,rver=ver<<1|1;
	if(x<=mid)
		add(l,mid,lver,x,y);
	else
		add(mid+1,r,rver,x,y);
	maxy[ver]=max(maxy[lver],maxy[rver]);
}

void rmv(int l,int r,int ver,int x,int y){
	if(!ver)
		return ;
	if(l==r){
		mem[ver].erase(y);
		if(mem[ver].size()){
			auto it=mem[ver].end();
			--it;
			maxy[ver]=*it;
		}
		else
			maxy[ver]=0;
		return ;
	}
	int mid=(l+r)>>1,lver=ver<<1,rver=ver<<1|1;
	if(x<=mid)
		rmv(l,mid,lver,x,y);
	else
		rmv(mid+1,r,rver,x,y);
	maxy[ver]=max(maxy[lver],maxy[rver]);
}

int check(int l,int r,int ver,int start,int end,int y){
	if(!ver)
		return 0;
	if(start<=l&&r<=end)
		return (maxy[ver]>y)?1:0;
	int mid=(l+r)>>1,lver=ver<<1,rver=ver<<1|1,ret=0;
	if(start<=mid&&maxy[lver]>y)	
		ret|=check(l,mid,lver,start,end,y);
	if(end>mid&&maxy[rver]>y)
		ret|=check(mid+1,r,rver,start,end,y);
	return ret;
} 

pair<int,int> binsearch(int l,int r,int ver,int x,int y){
	if(!ver)
		return make_pair(-1,-1);
	if(l==r){
		auto it=mem[ver].upper_bound(y);
		if(it==mem[ver].end())
			return make_pair(-1,-1);
		else
			return make_pair(l,*it);
	}
	int mid=(l+r)>>1,lver=ver<<1,rver=ver<<1|1;
	if(check(l,r,ver,x+1,mid,y))
		return binsearch(l,mid,lver,x,y);
	else
		return binsearch(mid+1,r,rver,x,y);
}

int main(){
	readi(n);
	for(int i=1;i<=n;i++){
		readstr(op+maxn),readi(recx[i]),readi(recy[i]);
		cpy.push_back(recx[i]);
		op[i]=op[maxn];
	}
	sort(cpy.begin(),cpy.end());
	int sz=unique(cpy.begin(),cpy.end())-cpy.begin();
	for(int i=1;i<=n;i++){
		int px=lower_bound(cpy.begin(),cpy.begin()+sz,recx[i])-cpy.begin()+1;
		mpx[px]=recx[i],recx[i]=px;
	}
	for(int i=1;i<=n;i++){
		if(op[i]=='a')
			add(1,sz+1,1,recx[i],recy[i]);
		if(op[i]=='r')
			rmv(1,sz+1,1,recx[i],recy[i]);
		if(op[i]=='f'){
			auto res=binsearch(1,sz+1,1,recx[i],recy[i]);
			if(res.first==-1)
				puts("-1");
			else{
				write(mpx[res.first]),putchar(' '),write(res.second);
				puts("");
			}
		}
	}	
	return 0;
}

如果你觉得这是 tlqtj 就举报吧,反正我只是想给后人一点帮助,同时给自己留个纪念(

2024/1/11 19:10
加载中...