《2020 Multi-University Training Contest 7》

Increasing and Decreasing

显然是一个构造的题,对于下降序列,我们用最后y的数来组成拼在后面。

对于x的上升序列。

我们要用剩下的数来拼凑成x-1个块(因为最后下降的块肯定比前面大)。

每个块里的元素都是下降序列即可。

为了最小化字典序,我们尽量让起前面的块尽可能小,注意的是,最少要有1。

对于NO时候的情况,由1 <= (n-y)/(x-1) <= y来推得

x+y <= n+1 && x+y <= n

坑点:这里len表示每个块的长度,需要开longlong,因为长度可能爆负int。。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef long double ld;
typedef pair<LL,int> pii;
const int N = 2e5+5;
const int M = 1e6+5;
const LL Mod = 998244353;
#define rg register
#define pi acos(-1)
#define INF 1e18
#define INM INT_MIN
#define dbg(ax) cout << "now this num is " << ax << endl;
inline int read()
{
    int x = 0,f = 1;char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
    return x*f;
}
LL len[N];
int main()
{
    int ca;ca = read();
    while(ca--)
    {
        int n,x,y;n = read(),x = read(),y = read();
        if(x+y > n+1 || 1LL*x*y < n){printf("NO\n");}
        else
        {
            int ma = n-y;
            for(int i = 1;i <= x-1;++i)
            { 
                len[i] = ma-1LL*(x-1-i)*y;
                if(len[i] <= 0) len[i] = 1;
                ma -= len[i];
            }
            printf("YES\n");
            int la = 0;
            for(int i = 1;i <= x-1;++i)
            {
                int tmp = la+len[i];
                for(int j = 1;j <= len[i];++j) printf("%d ",tmp-j+1);
                la += len[i];
            }
            for(int i = n;i >= n-y+1;--i) printf("%d%c",i,i == n-y+1 ? '\n' : ' ');
        } 
    }
    system("pause");
    return 0;
}
View Code

 

posted @ 2020-08-12 10:15  levill  阅读(218)  评论(0)    收藏  举报