CDQ求助
查看原帖
CDQ求助
999274
CNS_5t0_0r2楼主2024/4/23 13:43
#include<bits/stdc++.h>
#define mid ((l + r) >> 1)
using namespace std;
const int N = 5e5 + 9,V = 1e6 + 9,INF = 0x3f3f3f3f;
int n,m,opt_tot,max_x;
struct operation{
	int op,x,y;
} opt[N << 1];

struct node{
	int id,x,y;
} tmp[N << 1];
int top;
bool cmp(node op1,node op2){
	return ((op1.x ^ op2.x) ? op1.x < op2.x : op1.y < op2.y);
}
int ans[N << 1];
struct BinaryIndexedTree{
	int t[V];
	int lowbit(int x){
		return x & (-x);
	}
	int query(int pos){
		int ret = -INF;
		for(int i = pos;i;i -= lowbit(i))
			ret = max(ret,t[i]);
		return ret;
	}
	void update(int x,int y){
		for(int i = x;i <= max_x;i += lowbit(i))
			t[i] = max(t[i],y);
	}
	void clear(int x){
		for(int i = x;i <= max_x;i += lowbit(i)){
			if(t[i] == -INF)
				return;
			t[i] = -INF;
		}
	}
	BinaryIndexedTree(){
		memset(t,0xcf,sizeof t);
	}
} BIT;
void calc(int st,int ed,int delta,int dx,int dy){
	for(int i = st;i != ed;i += delta){
		int x = dx == 1 ? tmp[i].x : max_x - x + 1;
		int dist = dx * tmp[i].x + dy * tmp[i].y;
		if(opt[tmp[i].id].op == 1)
			BIT.update(x,dist);
		else
			ans[tmp[i].id] = min(ans[tmp[i].id],abs(dist - BIT.query(x)));
	}
	//撤销修改 
	for(int i = st;i != ed;i += delta){
		int x = dx == 1 ? tmp[i].x : max_x - x + 1;
		if(opt[tmp[i].id].op == 1)
			BIT.clear(x);
	}
}
void CDQ(int l,int r){
	if(l >= r)
		return;
	if(l <= mid) CDQ(l,mid);
	if(r > mid) CDQ(mid + 1,r);
	if(r > n){
		top = 0;
		//提取左区间的修改操作和右区间的查询操作 
		for(int i = l;i <= r;i++)
			if((i <= mid && opt[i].op == 1) || (i > mid && opt[i].op == 2))
				tmp[++top] = (node){i,opt[i].x,opt[i].y};
		//按横坐标排序 
		sort(tmp + 1,tmp + top + 1,cmp);
		//分4类讨论
        calc(1,top + 1,1,1,1);calc(1,top + 1,1,-1,1);
        calc(top,0,-1,1,-1);calc(top,0,-1,-1,-1);
	}
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	memset(ans,0x3f,sizeof ans);
	cin >> n >> m;
	for(int i = 1;i <= n;i++){
		int x,y;
		cin >> x >> y;
		x++;max_x = max(max_x,x);
		opt[++opt_tot] = (operation){1,x,y};
	}
	for(int i = 1;i <= m;i++){
		int op,x,y;
		cin >> op >> x >> y;
		x++;max_x = max(max_x,x);
		opt[++opt_tot] = (operation){op,x,y};
	}
	CDQ(1,opt_tot);
	for(int i = n + 1;i <= opt_tot;i++)
		if(opt[i].op == 2)
			cout << ans[i] << '\n';
	return 0;
}
2024/4/23 13:43
加载中...