【补题】Codeforces Round 715 (Div. 1) B. Almost Sorted
题意:
思路: Codeforces Round #715 (Div. 1) B. Almost Sorted 找规律_1508b - almost sorted-CSDN博客
非常妙,自己做的时候,我不仅没发现是2的幂,并且把2的幂用for循环算了出来
然后发现错了,这道题给出的k在特定情况下要反着算,很妙,现在想打自己一顿
1.可以发现如果要满足题目条件,一定是选择了某一块倒着来,比如 3 4 5 变 5 4 3
比如 1 2 3 4 变 2 1 4 3,反正选择一块倒着来, 这一块是我个人做的时候有点错误的方向,可以不用看,直接打表应该才是这题最简单的处理方式
2.可以自己模拟一下,也可以直接打表(确实更快),就会发现长度为n的序列,有2的n-1次幂种可能
3.然后对着表,或者说2进制枚举,倒着计算即可,因为n可能很长,正着计算是不可能的,爆数据范围了,最多62次改变,就结束了,字典序很明显从后
所以打表,规律很好发现,然后模拟出一样的效果即可
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define IOS \std::ios::sync_with_stdio(0); \std::cin.tie(0); \std::cout.tie(0)const int N = 3e5 + 5;
const int INF = 1e18;
const int MOD = 998244353;
// const int MOD=1e9+7;
// const int MOD=100003;
const int maxn=5e5+10;int qmi(int a,int b){int ans=1;while(b){if(b&1) ans=a*ans;b>>=1;a=a*a;}return ans;
}void solve(){int n,k;std::cin >> n >> k;if (n <= 62 && k > (1ll << (n - 1))) {cout << -1 << '\n';return;}k--;std::vector<int> is(70);for(int i=62;i>=0;i--){int now=((1ll<<i) & k);// cout << now << " " << k << "\n";if(now){is[i]=1;}}int last=n;int now=0;std::vector<int> ans;for(int i=0;i<min(n,70ll);i++){if(is[i]){now++;}else{for(int j=last-now;j<=last;j++){// cout << j << " ";ans.push_back(j);}last=last-now-1;now=0;}}for(int i=last;i>=1;i--){ans.push_back(i);}for(int i=ans.size()-1;i>=0;i--){cout << ans[i] << " ";}cout << '\n';}signed main(){IOS;int t=1;std::cin >> t;while(t--){solve();}
}