1. 程式人生 > 實用技巧 >《2020 Multi-University Training Contest 7》

《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