E. Almost Sorted(构造,递归)
生活随笔
收集整理的這篇文章主要介紹了
E. Almost Sorted(构造,递归)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
E. Almost Sorted
我們定義 almost sorted 數組為,ai+1≥ai?1a_{i + 1} \geq a_i - 1ai+1?≥ai??1,也就是說,
先寫幾項出來看看:
n = 1
1
n = 2
1 2
2 1
n = 3
1 2 3
1 3 2
2 1 3
3 2 1
容易發現一定是,形如x,x?1,x?2,…,1,…x, x - 1, x - 2, \dots, 1, \dotsx,x?1,x?2,…,1,…,這樣的,也就是前綴是一連串的下降的數字,
假設數字長度為nnn,前綴下降長度為mmm,則這樣的方案就是長度為n?mn - mn?m的排類的方案了,
假設f(n)f(n)f(n)表示長度為nnn的方案, 則f(n)=∑i=0n?1f(i)f(n) = \sum\limits_{i = 0} ^{n - 1} f(i)f(n)=i=0∑n?1?f(i),f(0)=1f(0) = 1f(0)=1,
到這里,其實就是解決若干個子問題了,所以就可以遞歸,或者 while 去構造了。
#include <bits/stdc++.h>using namespace std;int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);map<int, long long> mp;mp[0] = 1, mp[1] = 1, mp[2] = 2;for (int i = 3; i <= 62; i++) {mp[i] = mp[i - 1] * 2;}int T, n, cur;scanf("%d", &T);while (T--) {long long k, temp;scanf("%d %lld\n", &n, &k);temp = k - 1;int num = 0;while (temp) {num++;temp >>= 1;}num++;if (num > n) {puts("-1");continue;}for (int i = 1; i <= n - num; i++) {printf("%d ", i);}cur = n - num + 1;while (k) {if (k == (1ll << num - 1)) {for (int i = n; i >= n - num + 1; i--) {printf("%d ", i);}break;}long long sum = 0;while (num && sum + mp[num - 1] < k) {num--;sum += mp[num];}k -= sum;num--;for (int i = n - num; i >= cur; i--) {printf("%d ", i);}cur = n - num + 1;}puts("");}return 0; }總結
以上是生活随笔為你收集整理的E. Almost Sorted(构造,递归)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不破楼兰终不还的意思 不破楼兰终不还的译
- 下一篇: D. Cut and Stick(Cod