JOISC2019 D1

版权声明:转吧转吧这条东西只是来搞笑的。。 https://blog.csdn.net/jpwang8/article/details/89023514

BG


菜鸡选手跟风写题.jpg

A


这个A有点简单啊。。我们把A、B、A+B分别看作三维,那么就是裸的三维偏序问题了
一开始wa了一发因为没有管坐标相同的时候询问要在人的后面~

Code


#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define lowbit(x) (x&-x)

const int N=400005;

struct data {int x,y,z,id,typ;} p[N];

int s[N],b[N],ans[N],size;

int read() {
	int x=0,v=1; char ch=getchar();
	for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):v,ch=getchar());
	for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
	return x*v;
}

void add(int x,int v) {
	for (;x<=size;x+=lowbit(x)) s[x]+=v;
}

int get(int x) {
	int res=0;
	for (;x;x-=lowbit(x)) res+=s[x];
	return res;
}

bool cmpx(data a,data b) {
	if (a.x==b.x) {
		if (a.y==b.y) {
			if (a.z==b.z) return a.typ<b.typ;
			else return a.z>b.z;
		} else return (a.y>b.y);
	} else return (a.x>b.x);
}

bool cmpy(data a,data b) {
	if (a.y==b.y) {
		if (a.z==b.z) return a.typ<b.typ;
		else return a.z>b.z;
	} else return (a.y>b.y);
}

void solve(int l,int r) {
	if (l==r) return ;
	int mid=(l+r)>>1;
	solve(l,mid);
	solve(mid+1,r);
	std:: sort(p+l,p+mid+1,cmpy);
	std:: sort(p+mid+1,p+r+1,cmpy);
	for (int i=mid+1,j=l,cnt=0;i<=r;++i) {
		while (j<=mid&&p[j].y>=p[i].y) {
			if (!p[j].typ) add(p[j].z,1),cnt++; j++;
		}
		if (p[i].typ) ans[p[i].id]+=cnt-get(p[i].z-1);
	}
	for (int i=mid+1,j=l;i<=r;++i) {
		while (j<=mid&&p[j].y>=p[i].y) {
			if (!p[j].typ) add(p[j].z,-1); j++;
		}
	}
}

int main(void) {
	// freopen("data.in","r",stdin);
	// freopen("myp.out","w",stdout);
	int n=read(),m=read();
	rep(i,1,n) {
		p[i].x=read(),p[i].y=read();
		p[i].z=p[i].x+p[i].y;
		p[i].id=i,p[i].typ=0;
		b[i]=p[i].z;
	}
	rep(i,1,m) {
		int x=read(),y=read(),z=read();
		p[i+n]=(data) {x,y,z,i,1};
		b[i+n]=z;
	}
	std:: sort(b+1,b+n+m+1);
	size=std:: unique(b+1,b+n+m+1)-b-1;
	rep(i,1,n+m) p[i].z=std:: lower_bound(b+1,b+size+1,p[i].z)-b;
	std:: sort(p+1,p+n+m+1,cmpx);
	solve(1,n+m);
	rep(i,1,m) printf("%d\n", ans[i]);
	return 0;
}

B


没写,感觉贪心不是那么显然。先鸽着吧

C


这题非常有意思
首先我们可以找到两个点(x,y),一个点w在这条链上当且仅当Q(x,y,w)=w,那么我们就可以抠出一条链出来
考虑对这条链排序,那么比较也是基于“Q(x,a,b)返回谁谁距离x更近”这个结论做的。
于是我们就得到了一条有序的链和剩余许多棵子树,对这些子树做同样的操作,然后连起来就可以得到原树了

怎么得到y呢?当生成的树保证随机时我们可以随便选,这题不保证树随机那么我们就随机一个y。这个好像叫做随机点分治?证明的话大概是重心落在随机链上的概率 &gt; 1 2 &gt;\frac{1}{2} ,于是就是 O ( n log n ) O(n\log n) 的了

Code


#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define lowbit(x) (x&-x)

const int N=400005;

struct data {int x,y,z,id,typ;} p[N];

int s[N],b[N],ans[N],size;

int read() {
	int x=0,v=1; char ch=getchar();
	for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):v,ch=getchar());
	for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
	return x*v;
}

void add(int x,int v) {
	for (;x<=size;x+=lowbit(x)) s[x]+=v;
}

int get(int x) {
	int res=0;
	for (;x;x-=lowbit(x)) res+=s[x];
	return res;
}

bool cmpx(data a,data b) {
	if (a.x==b.x) {
		if (a.y==b.y) {
			if (a.z==b.z) return a.typ<b.typ;
			else return a.z>b.z;
		} else return (a.y>b.y);
	} else return (a.x>b.x);
}

bool cmpy(data a,data b) {
	if (a.y==b.y) {
		if (a.z==b.z) return a.typ<b.typ;
		else return a.z>b.z;
	} else return (a.y>b.y);
}

void solve(int l,int r) {
	if (l==r) return ;
	int mid=(l+r)>>1;
	solve(l,mid);
	solve(mid+1,r);
	std:: sort(p+l,p+mid+1,cmpy);
	std:: sort(p+mid+1,p+r+1,cmpy);
	for (int i=mid+1,j=l,cnt=0;i<=r;++i) {
		while (j<=mid&&p[j].y>=p[i].y) {
			if (!p[j].typ) add(p[j].z,1),cnt++; j++;
		}
		if (p[i].typ) ans[p[i].id]+=cnt-get(p[i].z-1);
	}
	for (int i=mid+1,j=l;i<=r;++i) {
		while (j<=mid&&p[j].y>=p[i].y) {
			if (!p[j].typ) add(p[j].z,-1); j++;
		}
	}
}

int main(void) {
	// freopen("data.in","r",stdin);
	// freopen("myp.out","w",stdout);
	int n=read(),m=read();
	rep(i,1,n) {
		p[i].x=read(),p[i].y=read();
		p[i].z=p[i].x+p[i].y;
		p[i].id=i,p[i].typ=0;
		b[i]=p[i].z;
	}
	rep(i,1,m) {
		int x=read(),y=read(),z=read();
		p[i+n]=(data) {x,y,z,i,1};
		b[i+n]=z;
	}
	std:: sort(b+1,b+n+m+1);
	size=std:: unique(b+1,b+n+m+1)-b-1;
	rep(i,1,n+m) p[i].z=std:: lower_bound(b+1,b+size+1,p[i].z)-b;
	std:: sort(p+1,p+n+m+1,cmpx);
	solve(1,n+m);
	rep(i,1,m) printf("%d\n", ans[i]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jpwang8/article/details/89023514
d1
今日推荐