334 字
2 分钟
CF1988C Increasing Sequence with Fixed OR 题解

CF1988C#

题意简述#

给定一个正整数 nn,要构造出一个长度为 kk 的严格递增序列 aa,且每一项 aina_i\le n。要满足 aiai1=na_i|a_{i-1}=n

题目分析#

要使得 aiai1=na_i|a_{i-1}=n,我们不妨先找找规律:

n=14n=14 时,可以构造出以下数据:

a1=6a_1=6

a2=10a_2=10

a3=12a_3=12

a4=14a_4=14

将其转化为 二进制

01100110
10101010
11001100
11101110

通过观察此数据,可以发现,构造出的数字的二进制存在规律,即将 nn 从末位开始将每个 11 都去除一次,这样可以使得相邻两个数的异或值都为 nn

Code#

#pragma GCC optimize(1, 2, 3, "Ofast", "inline")
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
#define ONLINE_JUDGE
#define MULTI_CASES
const int MaxN = 2e5+100;
const int INF = 1e9;
int T=1, N, M;
int a[MaxN];
int Atoi(string s,int radix) //s是给定的radix进制字符串
{
int ans=0;
for(int i=0;i<s.size();i++)
{
char t=s[i];
if(t>='0'&&t<='9') ans=ans*radix+t-'0';
else ans=ans*radix+t-'a'+10;
}
return ans;
}
//n是待转换的十进制数,m是待转换成的进制数
string intToA(int n,int m){
string ans="";
do{ //使用do{}while()循环类型以防止输入为0的情况
int t=n%m;
if(t>=0&&t<=9)
ans+=(t+'0');
else
ans+=(t+'a'-10);
n/=m;
}while(n);
reverse(ans.begin(),ans.end());
return ans;
}
inline void Solve()
{
cin>>N;
// char s1[MaxN];
string s;
s=intToA(N,2);
M=1;
// cout<<s<<endl;
for(int i=0;i<s.size();i++){
if(s[i]=='1'){
M++;
}
}
if(M==2){
cout<<1<<endl<<N<<endl;
return;
}
cout<<M<<endl;
for(int i=0;i<s.size();i++){
if(s[i]=='1'){
string str=s;
str[i]='0';
cout<<Atoi(str,2)<<" ";
}
}
cout<<N<<endl;
// cout<<endl;
// cout<<s<<endl;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen(".in", "r", stdin);
freopen(".out", "w", stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
#ifdef MULTI_CASES
cin >> T;
while (T--)
#endif
Solve();
//fclose(stdin);
//fclose(stdout);
return 0;
}
CF1988C Increasing Sequence with Fixed OR 题解
https://blog.introl.top/posts/cf1988c-increasing-sequence-with-fixed-or-题解/
作者
Introl
发布于
2024-07-16
许可协议
CC BY-NC-SA 4.0