【JZOJ5456】奇怪的队列【线段树】

题目大意:

题目链接:https://jzoj.net/senior/#main/show/5456
题目图片:
http://wx1.sinaimg.cn/mw690/0060lm7Tly1fwerg3tpiyj30jf0bigm3.jpg
http://wx2.sinaimg.cn/mw690/0060lm7Tly1fwerg3u33aj30k40gz3yu.jpg

给出nn个人的身高,第ii个人记得他的前面或者后面有a[i]a[i]个人比他高。这些人字典序最小的排列。


思路:

40分做法:

先将所有人的身高排序,然后DFSDFS全排列,再判断是否成立。
时间复杂度:O(n!n2)O(n!n^2)
代码

100分做法:

按照样例一来模拟

4
4 1
3 1
6 0
2 0

先按身高排序(从小到大)

4
2 0
3 1
4 1
6 0

首先,我们有一个长度为4的空串
在这里插入图片描述
身高为2,前(后)面有0个人比他高的人。那么很明显,就只能插入第一个或最后一个位置。
在这里插入图片描述
为了字典序最小,那么就将这个人插入到第一个位置。
在这里插入图片描述
然后看下一个人,身高为3,前(后)面有一个人比他高。
那么可能的位置也就只有一个,就插入三号位。

在这里插入图片描述
身高为4,前(后)面没有人比他高。
那么剩余两个位置都有可能。
在这里插入图片描述
选择字典序更小的。
在这里插入图片描述
那么最后一个人就只能放在最后一个位置了。
在这里插入图片描述
那么,我们就需要一个可以插入和查找的数据结构。那么很容易想到权值线段树。
然后就迎刃而解了。


代码;

#include <cstdio>
#include <algorithm>
#define N 100100
using namespace std;

int n,ans[N],f;
char c;

struct node
{
	int h,s;
}p[N];

struct Tree
{
	int l,r,num;
}tree[N*3];

int read()
{
	f=0;
	c=getchar();
	while (c<'0'||c>'9') c=getchar();
	while (c>='0'&&c<='9')
	{
		f=f*10+c-48;
		c=getchar();
	}
	return f;
}

void write(int x)
{
	if (x>9) write(x/10);
	putchar(x%10+48);
}

bool cmp(node x,node y)
{
	return x.h<y.h;
}

void make(int x)  //建树
{
	if (tree[x].l==tree[x].r) 
	{
		tree[x].num=1;  //表示这个区间的空位的个数
		return;
	}
	int mid=(tree[x].l+tree[x].r)/2;
	tree[x*2].l=tree[x].l;
	tree[x*2].r=mid;
	tree[x*2+1].l=mid+1;
	tree[x*2+1].r=tree[x].r;
	make(x*2);
	make(x*2+1);
	tree[x].num=tree[x*2].num+tree[x*2+1].num;
}

void find(int x,int num,int h)  //查询
{
	tree[x].num--;  //空位减一
	if (tree[x].l==tree[x].r)
	{
		ans[tree[x].l]=h;
		return;
	}
	if (num<tree[x*2].num) find(x*2,num,h);  //可以往左就往左
	else find(x*2+1,num-tree[x*2].num,h);
}

int main()
{
	n=read();
	for (int i=1;i<=n;i++)
	 p[i].h=read(),p[i].s=read();
	sort(p+1,p+1+n,cmp);
	for (int i=1;i<=n;i++)
	 if (p[i].s>n-i)
	 {
	 	printf("impossible");
	 	return 0;
	 }
	tree[1].l=1;
	tree[1].r=n;
	make(1);
	for (int i=1;i<=n;i++)
	 find(1,min(p[i].s,n-p[i].s-i),p[i].h);
	for (int i=1;i<=n;i++)
	{
		write(ans[i]);
		putchar(32);
	} 
	return 0;
}
posted @ 2018-10-20 16:39  全OI最菜  阅读(138)  评论(0编辑  收藏  举报