关于本人的常数
查看原帖
关于本人的常数
495512
Grimgod楼主2023/12/1 20:41

本人使用CDQ做法,然后本人的CDQ写法在本题上表现得比其他写法差了很多,猜测是常数问题,请问本人的常数因何而起?

#include<bits/stdc++.h>
using namespace std;
const int N=6e5;
const int M=1e6+5;
int n,m;
int tot;
int ch,g,h;
int c[M+5][2];
int ans[N+5];
bool que[N+5];
struct option{
	int x,y;
	int type,id,tim;
}opt[N+5];
bool cmp1(option x,option y){
	return x.tim<y.tim;
}
bool cmp2(option x,option y){
	if(x.x==y.x){
		return x.type<y.type;
	}
	return x.x<y.x;
}
bool cmp3(option x,option y){
	if(x.x==y.x){
		return x.type<y.type;
	}
	return x.x>y.x;
}
void change(int x,int delta,int id){
	for(int i=x;i<=M;i+=(i&-i)) c[i][id]=max(c[i][id],delta);
}
int query(int x,int id){
	int res=-0x3f3f3f3f;
	for(int i=x;i;i-=(i&-i)) res=max(res,c[i][id]);
	return res;
}
bool check(int x,int id){
	bool flag=1;
	for(int i=x;i;i-=(i&-i)) {
		if(c[i][id]!=-0x3f3f3f3f) flag=0; 
	}
	return flag;
}
void clear(int x,int id){
	for(int i=x;i<=M;i+=(i&-i)) c[i][id]=-0x3f3f3f3f;
}
void solve1(int l,int r){
	if(l==r) return ;
	int mid=(l+r)>>1;
	solve1(l,mid),solve1(mid+1,r);
	sort(opt+l,opt+1+mid,cmp2);
	sort(opt+1+mid,opt+1+r,cmp2);
	int pointer=l;
	for(int i=mid+1;i<=r;i++){
		if(!opt[i].type) continue;
		while(pointer<=mid&&opt[pointer].x<=opt[i].x){
			if(opt[pointer].type) {
				pointer++;
				continue;
			}
			change(opt[pointer].y,opt[pointer].x+opt[pointer].y,0);
			change(M-opt[pointer].y,opt[pointer].x-opt[pointer].y,1);
			pointer++;
		} 
		int res1=opt[i].x+opt[i].y-query(opt[i].y,0);
		int res2=opt[i].x-opt[i].y-query(M-opt[i].y-1,1);
		//cout<<res1<<" "<<res2<<endl;
		ans[opt[i].id]=min(ans[opt[i].id],min(res1,res2));
	}
	for(int i=l;i<pointer;i++) clear(opt[i].y,0),clear(M-opt[i].y,1);
}
void solve2(int l,int r){
	if(l==r) return ;
	int mid=(l+r)>>1;
	solve2(l,mid),solve2(mid+1,r);
	sort(opt+l,opt+1+mid,cmp3);
	sort(opt+1+mid,opt+1+r,cmp3);
	int pointer=l;
	for(int i=mid+1;i<=r;i++){
		if(!opt[i].type) continue;
		while(pointer<=mid&&opt[pointer].x>opt[i].x){
			if(opt[pointer].type) {
				pointer++;
				continue;
			}
			change(opt[pointer].y,-opt[pointer].x+opt[pointer].y,0);
			change(M-opt[pointer].y,-opt[pointer].x-opt[pointer].y,1);
			pointer++;
		} 
		int res1=-opt[i].x+opt[i].y-query(opt[i].y,0);
		int res2=-opt[i].x-opt[i].y-query(M-opt[i].y-1,1);
		//cout<<res1<<" "<<res2<<endl;
		ans[opt[i].id]=min(ans[opt[i].id],min(res1,res2));
	}
	for(int i=l;i<pointer;i++) clear(opt[i].y,0),clear(M-opt[i].y,1);
}
int main(){
	//freopen("P4169_11.in","r",stdin);
	//freopen("uncomparedoutput.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>m;
	memset(ans,0x3f,sizeof(ans));
	memset(c,-0x3f,sizeof(c));
	for(int i=1;i<=n;i++){
		cin>>g>>h;
		g++,h++;
		opt[++tot].x=g,opt[tot].y=h;
		opt[tot].tim=tot;
	}
	for(int i=1;i<=m;i++){
		cin>>ch>>g>>h;
		g++,h++;
		if(ch==1){
			opt[++tot].x=g,opt[tot].y=h,opt[tot].tim=tot;
		}
		else opt[++tot].x=g,opt[tot].y=h,opt[tot].tim=tot,opt[tot].type=1,opt[tot].id=i,que[i]=1;
	}
	solve1(1,tot);
	sort(opt+1,opt+1+tot,cmp1);
	solve2(1,tot);
	for(int i=1;i<=m;i++){
		if(que[i]) cout<<ans[i]<<endl; 
	}
	return 0;
}
2023/12/1 20:41
加载中...