计蒜客 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^51n105).

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[j1];
  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 2j2, |pos[j]-pos[j-1]|\le kpos[j]pos[j1]k (1 \le k \le 10^51k105). 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 n1kn, c_i=d_ici=di for all 1 \le i < k1i<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(1T20), 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^51n,k105), the second line contains nn distinct integers a_1, a_2, ..., a_na1,a2,...,an (1 \le a_i \le n1ain) 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序列  s[0]= i . 从 a中选择数字 , s序列是降序排列 ,满足最大字典序,且s中相邻的两个数 在a中的下标 绝对值的差小于k  pos[j]pos[j1]k  (1≤ ≤10^5) 

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

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

s在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  阅读(160)  评论(0编辑  收藏  举报