计蒜客 The Preliminary Contest for ICPC Asia Nanjing 2019

F    Greedy Sequence

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.

 

题解 :

输入  T组样例(T<=20)给定 n  k,   序列a是 1-n 乱序排列的一组数。

 

求 有n个 s序列  si [0]= i . 从 a中选择数字 , s序列是降序排列 ,满足最大字典序,且s中相邻的两个数 在a中的下标 绝对值的差小于k  ∣pos[j]−pos[j−1]∣≤k  (1≤ k ≤10^5) 

输出n个s序列中非0的个数。

从 s1 ={1,0,0,,,0}  答案为 ans=1.

s2 在s1 的基础上增加了 2 判断  新加入的2是否满足k ,即ans[2] =ans[1]+1.  从i 到 1  满足的则加上 ,否则不加。

ans[i]+=ans[j]; 每个s序列的ans[i] 需要从 1计算到 i 由 j 控制。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <cstring>
#include <queue>
#include <stack>
#include <cmath>
#define int long long
#define Mod 1000000007
#define pi (acos(-1))
#define inf 0x3f3f3f3f3f
#define Maxn 100005
using namespace std;

int a[Maxn];
int pos[Maxn];
int ans[Maxn];
signed main(){
    int t;
    scanf("%lld",&t);
    while(t--){
        int n,k;
        scanf("%lld%lld",&n,&k);
        for(int i = 1 ; i <= n ; i  ++ )
        {
            scanf("%lld",&a[i]);
            pos[a[i]]=i;
        }
//        for(int i = 0 ; i < n ; i ++ )
//        printf("%lld ",pos[i]);
//        ans[1]=1;
//        if(pos[2]-pos[1]<=k&&pos[2]-pos[1]>=-k)
//        ans[2]+=a[1];
//        printf("a2=%lld\n",a[2]);
        for(int i = 1 ; i <= n ; i ++ )
        {
            ans[i]=1;
            for(int j = i-1 ; j >= 1 ; j -- )
            {
                if(pos[i]-pos[j]>=-k&&pos[i]-pos[j]<=k)
                {
                    ans[i]+=ans[j];
//                    printf("%lld%lld%lld\n",i,i,i);
                    break;
                }
            }
        }
        for(int i = 1 ; i < n ; i ++ )
        printf("%lld ",ans[i]);
        printf("%lld\n",ans[n]);
    } 
    return 0;
}
View Code

 

 

 

posted @ 2019-09-04 09:02  Young-children  阅读(195)  评论(0)    收藏  举报