其他分享
首页 > 其他分享> > P4169 [Violet]天使玩偶

P4169 [Violet]天使玩偶

作者:互联网

这个cdq的板子还是很优秀的,我没有卡任何常数直接过了

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+5;
int inf=0x3f3f3f3f,C[N],n,m,tot=0,ans[N],len;
int lowbit(int u) {return u&(-u);}
void Update(int p,int d) {
	for(int i=p;i<=len;i+=lowbit(i)) C[i]=max(C[i],d);
}
int Ask(int p) {
	int mx=-inf;
	for(int i=p;i;i-=lowbit(i)) mx=max(mx,C[i]);
	return mx;
}
void Clear(int p) {
	for(int i=p;i<=len;i+=lowbit(i)) C[i]=-inf;
}
struct node {
	int opt,x,y,id;
}Q[N],a[N],t[N];
void CDQ(int l,int r) {
	if(l==r) return;
	int mid=(l+r)>>1;
	CDQ(l,mid),CDQ(mid+1,r);
	int i=l,j=mid+1,c=l;
	while(c<=r) {
		if((j>r)||(i<=mid&&Q[i].x<=Q[j].x)) {
			if(Q[i].opt==1) Update(Q[i].y,Q[i].x+Q[i].y);
			t[c++]=Q[i++];
		}
		else {
			if(Q[j].opt==2) ans[Q[j].id]=min(ans[Q[j].id],Q[j].x+Q[j].y-Ask(Q[j].y));
			t[c++]=Q[j++];
		}
	}
	for(int k=l;k<=mid;k++) if(Q[k].opt==1) Clear(Q[k].y);
	for(int k=l;k<=r;k++) Q[k]=t[k];
}
void _cdq(int fx,int fy) {
	for(int i=1;i<=tot;i++) {
		Q[i]=a[i];
		if(fx) Q[i].x=len-Q[i].x;
		if(fy) Q[i].y=len-Q[i].y;
	}
	CDQ(1,tot);
}
int main() {
	memset(ans,0x3f,sizeof(ans));
	memset(C,-0x3f,sizeof(C));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		++tot;
		scanf("%d%d",&a[tot].x,&a[tot].y); a[tot].opt=1,a[tot].id=tot;
		a[tot].x++,a[tot].y++;
		len=max(len,max(a[tot].x,a[tot].y));
	}
	for(int i=1;i<=m;i++) {
		tot++;
		scanf("%d%d%d",&a[tot].opt,&a[tot].x,&a[tot].y);
		a[tot].id=tot;
		a[tot].x++,a[tot].y++;
		len=max(len,max(a[tot].x,a[tot].y));
	}
	len++;
	_cdq(0,0),_cdq(0,1),_cdq(1,0),_cdq(1,1);
	for(int i=1;i<=tot;i++) {
		if(a[i].opt==2) {
			printf("%d\n",ans[i]);
		}
	}
	return 0;
}

标签:int,mid,len,玩偶,CDQ,Violet,inf,cdq,P4169
来源: https://www.cnblogs.com/bestime/p/15126092.html