【NOIP2015模拟9.12】SERN的野望

Description

Error! Human is dead. Mismatch.
SERN妄图研发出时间机器,然而现在却只有一堆失败的实验品。
然而,SERN妄图通过这些失败的试验品研究出正确的道路,而这首先就需要将这些失败的实验品归类。
每一个实验品有一个转移强度D和转移距离R。由于SERN血腥残忍、不择手段,所以所有实验品的转移强度均不相同,转移距离也均不相同。
SERN惊讶的发现,一个时间机器的性能极大地取决于它在高斯平面上的投影。
定义一个时间机器α在高斯平面上的投影λ(α)"傅里叶包含"【"傅里叶包含"记作")("】另一个时间机器β在高斯平面上的投影λ(β)【此关系记作"α)(β"】,当且仅当α的转移强度大于β的转移强度且α的转移距离大于β的转移距离。
定义黎曼-洛伦兹函数ζ(A,S)为真当且仅当在实验品集合S中的任何实验品在高斯平面上的投影都不傅里叶包含实验品A在高斯平面上的投影,亦即对于任意B∈S,"B)(A"不成立。
而对实验品的归类方式可以分为以下几个步骤:
S1:令i=0
S2:令i=i+1 令S=还没被分组的实验品集合
S3:对于每一件S中的武器A,如果黎曼-洛伦兹函数ζ(A,S)为真,则将武器A标记为第i组
【注意S在这个过程中始终保持不变,这称为分组的牛顿-科特斯一致性】
S4:如果所有实验品均被分组则结束,否则转S2
 
给定N个实验品的D和R,你的任务是将其分组。

Input

输入文件的第一行包含一个正整数N,表示实验品的个数。
接下来N行,每行两个正整数D,R,描述一个实验品的D和R.

Output

输出文件包含N行,每行一个正整数,第i行的数表示第i个实验品被分在了哪一组。

Sample Input

5
1 4
2 2
3 3
4 1
5 5

Sample Output

2
3
2
2
1

Data Constraint

对于20%的数据,N<=100
对于40%的数据,N<=3000
对于100%的数据,N<=100000,1<=R,D<=10^9

Source / Author: 常州高级中学 tank

题意:

什么乱七八糟的

在平面直角坐标系上,给你n点,现在有若干轮操作,每一次操作可以取走一些点(满足以他为原点建立坐标系,它的第一象限没有点,也就是它的右上方没有点),第i轮取走的点分到第i组,问所有点的组别。

题解:

按D从大到小排序。

假设i之前已放完,现在要把i分组。

设目前已经有了k组,并设第i组里最大的R值为maxR(i)

易知maxR(i)随i递减

证明:


设待加入实验品的R值为R*
则这件武器必然会被加入第i组,其中i是最小的让maxR(i)<R*成立的i值
二分查找i并更新相应的maxR值即可

把样例画下来,很清晰地可以把它们分组。

按D从大到小排序后,就是在坐标系上从右到左。

显然右上角的分到Group1. maxR = {5}

(4,1)显然分到G2。maxR = {5,1}

(3,3)“R*”为3。maxR[1] = 5 。5>3。而maxR[2] = 1。1<3 。因此这个点可以分到G2。

具体地说,就是对于横坐标大于此点的,如果其纵坐标也大于此点,也就是在这个点的右上方,那么就不能和它分一个组。

(所以,则这件武器必然会被加入第i组,其中i是最小的让maxR(i)<R*成立的i值)maxR = {5,3}

到(2,2),“R*”为2,可是没有maxR[]小于它,分到G3。

。。。

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define rint register ll
#define N 100010
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
#define INF 2147483647
using namespace std;

struct point
{int x,y,id;}a[N];

int n,i,j,t,ans[N];
int maxR[N];

bool cmp(point x,point y)
{return x.x > y.x;}

int binary(int y)
{
	int l=1,r=t,mid=0;
	while(l<=r)
	{	
		mid = (l+r)>>1;
		if(maxR[mid] < y) r= mid-1; else l = mid +1;
	}
	return r+1;
}

int main()
{
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y),a[i].id=i;
	sort(a+1,a+1+n,cmp);
	for(i=1;i<=n;i++)
	{
		int k = binary(a[i].y);
		if(k > t)(k=++t),maxR[t] = a[i].y; else maxR[k] = a[i].y;
		ans[a[i].id]=k;
	}
	for(i=1;i<=n;i++)printf("%d\n",ans[i]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Com_man_der/article/details/88912945