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。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }