The Preliminary Contest for ICPC Asia Xuzhou 2019 E XKC's basketball team(排序+二分)

这题其实就是瞎搞,稍微想一想改一改就能过。
排序按值的大小排序,之后从后向前更新node节点的loc值,如果后一个节点的loc大于(不会等于)前一个节点的loc,就把前一个节点的loc值设置为后面的loc值。
这样的话, 后面的节点的值是大于前面节点的,如果该节点的loc也大于前面节点的,说明前面节点的loc就没有用了,用后面更大的数的更大的loc就可以了。
之后是一个二分,二分写的时候要把各种情况处理清楚,比如,m的值为0,搜索的时候可能会搜到它自己,所以如果搜索val+m,搜到的节点的loc<=i的话,说明就是它本身,或者就是一个比它大的值,m不为0,但是loc却小于了i,说明这个也是无效值。
以及val+m之后值过大,搜索不到,此时的l就会大于n,或者最后搜到的val大于了我们要搜的val,但是位置也小于我们当前的位置i,此时也是无效值,返回-1就可以了。
这题的二分搜索处理好就可以了,复杂度2e7左右。

#include <bits/stdc++.h>
using namespace std;
const int maxn=5e5+10; 

struct Node {
	long long val,loc;
}node[maxn];

long long num[maxn];
long long n,m;

bool cmp(const Node &a,const Node &b)
{
	if (a.val!=b.val) {
		return a.val<b.val;
	}
	return a.loc<b.loc;
}

long long BinarySearch(long long val,int i)
{
	long long l=1,r=n,mid;
	while (l<=r) {
		mid=(l+r)/2;
		if (node[mid].val==val) {
			if (node[mid].loc<=i) {
				return -1;
			}
			else {
				return node[mid].loc-i-1;
			}
		}
		else if (node[mid].val<val) {
			l=mid+1;
		}
		else {
			r=mid-1;
		}
		// printf("%lld %lld %lld\n",l,r,mid);
	}
	return l>n||node[l].loc<=i?-1:node[l].loc-1-i;
}

int main()
{
	scanf("%lld%lld",&n,&m);
	for (int i=1;i<=n;i++) {
		scanf("%lld",&node[i].val);
		node[i].loc=i;
		num[i]=node[i].val;
	}
	sort(node+1,node+n+1,cmp);
	for (int i=n;i>1;i--) {
		if (node[i].loc>node[i-1].loc) {
			node[i-1].loc=node[i].loc;
		}
		// printf("%lld %lld\n",node[i].val,node[i].loc);
	}
	for (int i=1;i<n;i++) {
		printf("%lld ",BinarySearch(num[i]+m,i));
	}
	printf("%lld\n",BinarySearch(num[n]+m,n));

    return 0;
}
/*
5 0
5 5 5 5 5
9 2
1 2 3 4 10 7 8 11 9
7 2
1 2 10 3 1 3 2
7 2
1 9 10 3 1 3 2
5 0
1 4 3 2 2
5 2
1 4 3 2 2
*/

posted @ 2019-09-28 10:13  xyee  阅读(102)  评论(0编辑  收藏  举报