【2019icpc南京站网络赛 - F】Greedy Sequence(思维,贪心构造,STLset)

34 篇文章 0 订阅

题干:

You're given a permutation aa of length nn (1 \le n \le 10^51≤n≤105).

For each i \in [1,n]i∈[1,n], construct a sequence s_isi​ by the following rules:

  1. s_i[1]=isi​[1]=i;
  2. The length of s_isi​ is nn, and for each j \in [2, n]j∈[2,n], s_i[j] \le s_i[j-1]si​[j]≤si​[j−1];
  3. First, we must choose all the possible elements of s_isi​ from permutation aa. If the index of s_i[j]si​[j] in permutation aa is pos[j]pos[j], for each j \ge 2j≥2, |pos[j]-pos[j-1]|\le k∣pos[j]−pos[j−1]∣≤k (1 \le k \le 10^51≤k≤105). And for each s_isi​, every element of s_isi​ must occur in aa at most once.
  4. After we choose all possible elements for s_isi​, if the length of s_isi​ is smaller than nn, the value of every undetermined element of s_isi​ is 00;
  5. For each s_isi​, we must make its weight high enough.

Consider two sequences C = [c_1, c_2, ... c_n]C=[c1​,c2​,...cn​] and D=[d_1, d_2, ..., d_n]D=[d1​,d2​,...,dn​], we say the weight of CC is higher thanthat of DD if and only if there exists an integer kk such that 1 \le k \le n1≤k≤n, c_i=d_ici​=di​ for all 1 \le i < k1≤i<k, and c_k > d_kck​>dk​.

If for each i \in [1,n]i∈[1,n], c_i=d_ici​=di​, the weight of CC is equal to the weight of DD.

For each i \in [1,n]i∈[1,n], print the number of non-zero elements of s_isi​ separated by a space.

It's guaranteed that there is only one possible answer.

Input

There are multiple test cases.

The first line contains one integer T(1 \le T \le 20)T(1≤T≤20), denoting the number of test cases.

Each test case contains two lines, the first line contains two integers nn and kk (1 \le n,k \le 10^51≤n,k≤105), the second line contains nn distinct integers a_1, a_2, ..., a_na1​,a2​,...,an​ (1 \le a_i \le n1≤ai​≤n) separated by a space, which is the permutation aa.

Output

For each test case, print one line consists of nn integers |s_1|, |s_2|, ..., |s_n|∣s1​∣,∣s2​∣,...,∣sn​∣ separated by a space.

|s_i|∣si​∣ is the number of non-zero elements of sequence s_isi​.

There is no space at the end of the line.

样例输入复制

2
3 1
3 2 1
7 2
3 1 4 6 2 5 7

样例输出复制

1 2 3
1 1 2 3 2 3 3

题目大意:

给你一个1~n的排列

解题报告:

首先贪心的思想,每个元素的下一个元素一定是与他距离不超过 k 的所有元素中,权值最大的元素,所以每个元素的下一个元素是固定的,我们可以通过滑动窗口 + set 上二分的预处理计算出每个元素的下一个元素,之后通过一个记忆化搜索即可 O(n) 求出每一个贪心序列的长度。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5; 
int a[MAX];
int n,q;
set<int> ss;
int db[MAX];//cun index
int ans[MAX];
int k;
int main()
{
	int T;
	cin>>T;
	while(T--) {
		scanf("%d%d",&n,&k);
		ss.clear();
		for(int i = 1; i<=n; i++) scanf("%d",a+i);
		int l=1-k,r=1+k;
		for(int i = 1; i<=r; i++) ss.insert(a[i]);
		for(int i = 1; i<=n; i++) {	
			l = i-k,r = i+k;
			auto it = ss.lower_bound(a[i]);
			if(it != ss.begin()) {
				it--;
				db[a[i]] = (*it);
			}
			else db[a[i]] = 0;			
			if(l >= 1) {
				auto it = ss.lower_bound(a[l]);
				ss.erase(it);
			}
			if(r+1<=n) {
				ss.insert(a[r+1]);
			}
		}
		for(int i = 1; i<=n; i++) ans[i] = ans[db[i]]+1;
		for(int i = 1; i<=n; i++) {
			printf("%d%c",ans[i],i == n ? '\n' :' ');
		}
	}
	return 0 ;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值