题意:
给出n个骑士,进行k次对战,每个骑士只能与另一个骑士对战一次,如果第i回合A对战B,C对战D,那么如果第j回合A对战C(D),那么B一定对战D©。问是否可能构成k场对局。字典序从小到大。
分析:
我们看最小的字典序,也就是我们想到的最优的不过就是
1 2 3 4 5 6 7 8 (然而这个不能用,本人不能跟本人对战)
2 1 4 3 6 5 8 7 (那么我们只好选优,肯定12互换,34互换)
3 4 1 2 7 8 5 6 (2用过了,我们看是以三打头就是介样子。)
…
最终就是这样子
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8bMZlsNV-1635941280451)(https://secure.wostatic.cn/static/nr6MSRJBGp92FDUiM66d4z/image.png)]](https://i-blog.csdnimg.cn/blog_migrate/f987b70399839c93086302a4d7b4e245.png)
通过观察,我们就能发现其中的规律,先是长度为2交换然后长度为4 ,然后长度2然后8然后2,然后4然后2像不像树状数组!
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0yxZt6nR-1635941280455)(https://secure.wostatic.cn/static/rvnAJFRWkUoboSwkEgUpHq/image.png)]](https://i-blog.csdnimg.cn/blog_migrate/d6fa0a81f2ad7850ad48467eee9cbd31.png)
然后我们我们只需要判断出是否可行,一共可以进行lowbit(n)-1轮超过这个就不可能实现。
然后我们只需要构造出每轮谁与谁对战即可。
大佬
/// 欲戴皇冠,必承其重。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<string, string> pii;
typedef unsigned long long ull;
#define x first
#define y second
#define PI acos(-1)
#define inf 0x3f3f3f3f
#define lowbit(x) ((-x)&x)
#define debug(x) cout << #x << ": " << x << endl;
const int MOD = 998244353;
const int mod = 998244353;
const int N = 5e5 + 10;
const int dx[] = {0, 1, -1, 0, 0, 0, 0};
const int dy[] = {0, 0, 0, 1, -1, 0, 0};
const int dz[] = {0, 0, 0, 0, 0, 1, -1};
int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
ll n, m;
ll a[N];
void solve()
{
scanf("%lld%lld",&n,&m);
if(m>lowbit(n)-1){
puts("Impossible");
}else {
for(int i=1;i<=n;i++){
a[i]=i;
}
for(ll i =1;i<=m;i++){
ll len=lowbit(i);
for(ll j=1;j<=n;j+=(len<<1)){
for(ll k=0;k<len;k++){
swap(a[j+k],a[j+len*2-1-k]);
}
}
for(int j=1;j<n;j++){
cout<<a[j]<<" ";
}
cout<<a[n]<<endl;
}
}
}
int main()
{
ll t = 1;
scanf("%lld", &t);
while(t--)
{
solve();
}
return 0;
}

578

被折叠的 条评论
为什么被折叠?



