[Luogu P4169] Angel Doll/SJY Playing Chess [CDQ Divide and Conquer]


Topic: Dynamic Point Addition. Ask Manhattan's nearest point at a given point

N,M≤3e5,x,y≤1e6N,M \leq 3e5,x,y \leq 1e6N,M≤3e5,x,y≤1e6

After (kan) Le (ti) analysis (jie), this is a cdqcdqcdq Division

Consider the influence of the modification of the left half of the current interval on the query on the right half

Let one on the left be modified to (x1, y1) (x1, y1) (x1, y1) and one on the right be (x2, y2) (x2, y2) (x2, y2)

Considering the cases of X1 < x2,y1 < Y2 x_1 Leq x_2, y1 Leq y_2x1 < x2,y1 < y2, the answer is x2+y2 x1 y1x_2 + y2-x_1-y_1x_2 + Y2 X1 y1

Because coordinates are linear, you need to sort out one dimension.

Sort left and right in xxx coordinates

This allows you to remove the xxx restriction with double pointers

The y YYY coordinate opens a tree array and records no more than the largest x+yx+yx+y in yyy's modifications

Then it's easy to calculate the answer.

The other three cases are similar.

In order to achieve convenience, the coordinate system is rotated directly, i.e. infinfinf subtraction.

Tree arrays already have logloglog logs, and we have no fear, so we can sort them directly.

Complexity O(NlogN2)O(Nlog_N^2)O(NlogN2)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 600005
#define MAXM 2000005
#define MAX 1000000
using namespace std;
inline int read()
	int ans=0;
	char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
int n,m,siz;
struct BIT
	int s[MAXM];
	inline int lowbit(const int& x){return x&-x;}
	inline void modify(int x,const int& v){for (;x<=(MAX<<1);s[x]=max(s[x],v),x+=lowbit(x));}
	inline int query(int x){int ans=-0x3f3f3f3f;for (;x;ans=max(ans,s[x]),x-=lowbit(x));return ans;}
	inline void clear(int x){for (;x<=(MAX<<1);s[x]=-0x3f3f3f3f,x+=lowbit(x));}
int ans[MAXN];
struct query{int type,x,y,pos;}q[MAXN];
inline bool operator <(const query& a,const query& b){if (a.x==b.x) return a.y<b.y;return a.x<b.x;}
void calc(int l,int r)
	int now=l-1,mid=(l+r)>>1;
	for (int i=mid+1;i<=r;i++)
		if (q[i].type==1) continue;
		while (now<mid&&q[now+1].x<=q[i].x) 
			if (q[now].type==1) bit.modify(q[now].y,q[now].x+q[now].y);
	for (int i=l;i<=mid;i++) bit.clear(q[i].y);	
void cdq(int l,int r)
	if (l==r) return;
	int mid=(l+r)>>1;
	for (int i=l;i<=r;i++) q[i].x=MAX-q[i].x;
	for (int i=l;i<=r;i++) q[i].y=MAX-q[i].y;
	for (int i=l;i<=r;i++) q[i].x=MAX-q[i].x;
	for (int i=l;i<=r;i++) q[i].y=MAX-q[i].y;
int main()
	for (int i=1;i<=n;i++) q[i].type=1,q[i].x=read()+1,q[i].y=read()+1;
	for (int i=1;i<=m;i++) q[n+i].type=read(),q[n+i].x=read()+1,q[n+i].y=read()+1,q[n+i].pos=i;
	for (int i=0;i<MAXM;i++) bit.s[i]=-0x3f3f3f3f;
	for (int i=1;i<=m;i++)
		if (ans[i]<0x3f3f3f3f)
	return 0;

Posted by n9ne on Thu, 10 Oct 2019 10:25:42 -0700