简单cdq分治求条
查看原帖
简单cdq分治求条
416192
kbzcz楼主2024/4/2 14:02

50pts,感觉是个小锅,哪位好心人帮忙看看/bx

bool _Start;
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define Tp template<typename T>
#define Ts template<typename T,typename... _T>
Tp il void read(T& x) {
	x=0;bool f=0;char c=getchar();
	for(;!isdigit(c);c=getchar()) f|=c=='-';
	for(;isdigit(c);c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	x=(f?-x:x);
}Ts il void read(T& x,_T&... y) {read(x),read(y...);}
const int N=1e5+5;
int n,T,ans;
int ln;
vector<int> ls;
struct node {
	double t;
	int id,op,x[3];
}a[N<<2],b[N],tmp[N<<2];int cnt;
void lsnum() {
	sort(ls.begin(),ls.end());
	ls.erase(unique(ls.begin(),ls.end()),ls.end());
	ln=ls.size();
	for(int i=1;i<=n;i++) {
		a[i].x[1]=lower_bound(ls.begin(),ls.end(),a[i].x[1])-ls.begin()+1;
		a[i].x[2]=lower_bound(ls.begin(),ls.end(),a[i].x[2])-ls.begin()+1;
	}
}
il bool cmp(node x,node y) {return x.t<y.t;}
int sum[N<<1];
il int lowbit(int k) {return k&-k;}
il void add(int x,int k) {
	for(;x<=ln;x+=lowbit(x))
		sum[x]+=k;
}
il int query(int x) {
	int res=0;
	for(;x;x-=lowbit(x))
		res+=sum[x];
	return res;
}
il void clear(int x) {
	for(;x<=ln&&sum[x];x+=lowbit(x))
		sum[x]=0;
}
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,len=0;
	for(;j<=r;j++) {
		for(;i<=mid&&a[i].x[0]<a[j].x[0];i++) {
			tmp[++len]=a[i];
			if(a[i].op!=2) add(a[i].x[1],a[i].op);
		}
		tmp[++len]=a[j];
		if(a[j].op==2) ans+=query(a[j].x[2])-query(a[j].x[1]);
	}
	for(;i<=mid;i++) tmp[++len]=a[i];
	for(;j<=r;j++) tmp[++len]=a[j];
	for(int k=l;k<=mid;k++) {
		if(a[k].op!=2) clear(a[k].x[1]);
	}
	for(int k=l;k<=r;k++) a[k]=tmp[k-l+1];
}
bool _End;
int main() {
//	fprintf(stderr,"Memory: %.4lf Mib\n",abs(&_End-&_Start)/1048576.0);
	read(n,T);
	for(int i=1;i<=n;i++) {
		read(a[i].x[1],a[i].x[2]);
		ls.push_back(a[i].x[1]);
		ls.push_back(a[i].x[2]); 
	}
	lsnum();
	for(int i=1;i<n;i++) {
		b[i].t=b[i].id=i;
		if(a[i].x[1]==a[i+1].x[1]) {
			b[i].op=1;
			b[i].x[0]=a[i].x[1];
			b[i].x[1]=min(a[i].x[2],a[i+1].x[2]);
			b[i].x[2]=max(a[i].x[2],a[i+1].x[2]);
		}
		else {
			b[i].op=2;
			b[i].x[0]=min(a[i].x[1],a[i+1].x[1]);
			b[i].x[1]=max(a[i].x[1],a[i+1].x[1]);
			b[i].x[2]=a[i].x[2];
		}
	}
	n--;
	for(int i=1;i<=n;i++) {
		if(b[i].op==1) {
			cnt++;
			a[cnt]=b[i];a[cnt].t-=T-0.5;a[cnt].op=2;
		}
		else {
			cnt++;
			a[cnt].op=1,a[cnt].t=b[i].t,a[cnt].x[0]=b[i].x[0],a[cnt].x[1]=b[i].x[2];
			cnt++;
			a[cnt].op=-1,a[cnt].t=b[i].t,a[cnt].x[0]=b[i].x[1],a[cnt].x[1]=b[i].x[2];
		}
	}
	sort(a+1,a+1+cnt,cmp);
	cdq(1,cnt);
	cnt=0;
	for(int i=1;i<=n;i++) {
		if(b[i].op==1) {
			cnt++;
			a[cnt]=b[i];a[cnt].t+=T-0.5;a[cnt].op=2;
		}
		else {
			cnt++;
			a[cnt].op=1,a[cnt].t=b[i].t,a[cnt].x[0]=b[i].x[0],a[cnt].x[1]=b[i].x[2];
			cnt++;
			a[cnt].op=-1,a[cnt].t=b[i].t,a[cnt].x[0]=b[i].x[1],a[cnt].x[1]=b[i].x[2];
		}
	}
	for(int i=1;i<=cnt;i++) a[i].t=1e9-a[i].t;
	sort(a+1,a+1+cnt,cmp);
	cdq(1,cnt);
	printf("%d\n",ans);
	return 0;
}

附带一组hack:

8 3
9 6
10 6
10 18
10 20
10 7
1 7
1 6
1 20
2024/4/2 14:02
加载中...