题目链接
题意:找出正整数n的一个排列
p
p
p,使得其为满足以下条件的序列
-
(
p
i
OR
p
i
+
1
OR
…
OR
p
j
−
1
OR
p
j
)
≥
j
−
i
+
1
(p_i \text{ OR } p_{i+1} \text{ OR } \ldots \text{ OR } p_{j-1} \text{ OR } p_{j}) \ge j-i+1
(pi OR pi+1 OR … OR pj−1 OR pj)≥j−i+1
(
1
≤
i
≤
j
≤
n
)
(1 \le i \le j \le n)
(1≤i≤j≤n)
也就是每个子序列的按位或之和不小于其中元素的数量。
思路:先说结论:输出任意一个排列即可
我们不难发现以下事实:对于任意一组数字,其按位或之和必然不小于其中的最大值,即:
( p i OR p i + 1 OR … OR p j − 1 OR p j ) ≥ m a x { p i , p i + 1 , . . . , p j } (p_i \text{ OR } p_{i+1} \text{ OR } \ldots \text{ OR } p_{j-1} \text{ OR } p_{j}) \ge max\{p_i,p_{i+1},...,p_j\} (pi OR pi+1 OR … OR pj−1 OR pj)≥max{pi,pi+1,...,pj}
所以只需子序列中元素的最大值大于等于其长度即可,假设:子序列长度为 n n n,最大元素小于n。那么我们有 n n n个元素的范围都在 [ 1 , n − 1 ] [1,n-1] [1,n−1]内,根据抽屉原理,必然有两者相同,这与题目给定的 p p p是排列的条件矛盾,所以任意的排列都满足题意。
AC代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main() {
ios::sync_with_stdio(0);
ll t, n;
cin >> t;
while (t--) {
cin>>n;
for(int i=n;i>=1;i--) cout<<i<<' ';cout<<endl;
}
return 0;
}