2024.11.23 CodeTON Round 9 (Div. 1 + Div. 2)

Solved:6/11

Rank:135


感觉 F 差一步就做出来了。。。


A. Shohag Loves Mod

题意:给 n,构造一个递增序列使得 {aimodi} 两两不同。

{2i1}

#include<bits/stdc++.h>
using namespace std;
void solve(){
int n;
cin>>n;
for(int i=1;i<=n;++i)cout<<i*2-1<<' ';
cout<<'\n';
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int T;
cin>>T;
while(T--)solve();
}

B. Shohag Loves Strings

题意:给一个字符串,求任意一个子串使得本质不同子串数量为偶数。

注意到 aaabc 的本质不同子串数都是偶数,而不存在这类子串的字符串只有形如 abababab...,其所有子串的本质不同子串数均为奇数。

#include<bits/stdc++.h>
using namespace std;
void solve(){
string a;
cin>>a;
int n=a.length();
for(int i=0;i<n-1;++i)if(a[i]==a[i+1]){cout<<a[i]<<a[i+1]<<'\n';return;}
bool fl=0;
for(int i=2;i<n;++i)if(a[i]!=a[i&1])fl=1;
if(!fl){cout<<"-1\n";return;}
for(int i=0;i<n-2;++i)if(a[i]!=a[i+1]&&a[i]!=a[i+2]&&a[i+1]!=a[i+2]){cout<<a[i]<<a[i+1]<<a[i+2]<<'\n';return;}
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int T;
cin>>T;
while(T--)solve();
}

C1. Shohag Loves XOR (Easy Version)

题意:给定 x,n,求 1yn 中有多少个 y 满足 (xy)|x(xy)|yx106,n1018

y 的二进制最高位比 x 高时,一定有 xy>xxy>y2。此时不可能存在整除关系。因此直接从 1min(n,2k1) 枚举 y 即可。这里 2k2 大于 x 的最小幂次。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve(){
int x;
ll n;
cin>>x>>n;
int m=1;
while(m<=x)m<<=1;
m=min((ll)m,n);
int cnt=0;
for(int i=1;i<=m;++i)if(i!=x){
if(!(x%(x^i))||!(i%(x^i)))++cnt;
}
cout<<cnt<<'\n';
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int T;
cin>>T;
while(T--)solve();
}

C2. Shohag Loves XOR (Hard Version)

题意:给定 x,n,求 1yn 中有多少个 y 满足 x|(xy)y|(xy)x106,n1018

和 C1 类似,当 y 的二进制最高位比 x 高时,xy 不可能是 y 的倍数,只可能是 x 的倍数。问题转化为统计有多少 q 满足 qxxn。当 qxnk 位之前不相等时,qxn 就等价于 qxxn,可以直接计算;故只需统计 qxxnk 位之前相等的情况,这部分可以暴力枚举;另外 y 很小的部分也可以暴力枚举(注意要减掉重复的)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve(){
int x;
ll n;
cin>>x>>n;
int m=1;
while(m<=x)m<<=1;
if(m>=n){
ll cnt=0;
for(int i=1;i<=n;++i){
if(!((x^i)%i)||!((x^i)%x))++cnt;
}
cout<<cnt<<'\n';
return;
}
ll cnt=0;
for(int i=1;i<m;++i){
if(!((x^i)%i)&&(x^i)%x)++cnt;
}
ll l=n^(n&(m-1)),r=l+m;
cnt+=(l-1)/x;
for(ll y=(l-1)/x*x+x;y<r;y+=x){
if((x^y)<=n)++cnt;
}
cout<<cnt<<'\n';
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int T;
cin>>T;
while(T--)solve();
}

D. Shohag Loves GCD

题意:给定 n 和一个大小为 m 的集合 S,构造一个序列,满足序列中所有数都属于 Sgcd(ai,aj)agcd(i,j),ij

设整数 x 的质因子数量(计重数)为 f(x)。当 mM=maxi=1nf(i) 时,满足题意的序列一定不存在。

证明:此时一定存在下标序列 p0,p1,pM 使得 p0|p1||pM。根据抽屉原理,一定有两个 pi,pj 满足 api=apj,而 gcd(pi,pj)=pi,gcd(api,apj)=api,不合题意。

而另一方面,当 m>M 时,我们只需将 S 从大到小排序并令 ai=sf(i) 即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
const int N=1e5+5;
bool np[N];
int pri[N],cnt,f[N],mx[N];
void sieve(int n){
for(int i=2;i<=n;++i){
if(!np[i])pri[++cnt]=i,f[i]=1;
for(int j=1;j<=cnt&&i*pri[j]<=n;++j){
np[i*pri[j]]=1;
f[i*pri[j]]=f[i]+1;
if(!(i%pri[j]))break;
}
}
for(int i=1;i<=n;++i)mx[i]=max(f[i],mx[i-1]);
}
void solve(){
int n,m;
cin>>n>>m;
vector<int> a(m);
for(int i=0;i<m;++i)cin>>a[i];
if(m<=mx[n]){cout<<"-1\n";return;}
sort(all(a)),reverse(all(a));
for(int i=1;i<=n;++i)cout<<a[f[i]]<<' ';
cout<<'\n';
}
int main(){
sieve(1e5);
ios::sync_with_stdio(0);cin.tie(0);
int T;
cin>>T;
while(T--)solve();
}

E. Shohag Loves Inversions

题意:初始序列为 [0,1],每次可将当前序列的逆序对数插入任意一个位置,求最终能生成的长度为 n 的序列的数量。对 998244353 取模。

插入一个数字在绝大多数情况下都会使序列的逆序对数增加。事实上,除了前几次操作插入 0,1 外,只要序列的逆序对数 2,那么除非插在序列末尾,插在其他任何位置都会使逆序对数增加。

fn 为:除末尾相同的和下次插入相等的数外,长度为 n+1,且序列逆序对数 2 的方案数。边界为 f1=f2=0,f3=2。对新插入的数字分三种情况讨论:

  • 新的数字是 1 且插入在前面:手玩可知逆序对数为 1 的序列只能形如 00...01011...1,能构成的新序列总数为 2+3++(n1)+n=(n1)(n+2)2

  • 新的数字 2 且插入在前面:由于此时末尾的数都不再是和下次插入相等的数,所以要考虑前面有 3n1 个数的情形,方案总数为 i=3n1(i+1)fi

  • 新的数字 2 且插入在末尾:没有贡献。

因此 fn=(n1)(n+2)2+i=3n1(i+1)fi,答案为 n1+i=3n1fin 是逆序对数 1 的方案数)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
const int N=1e6+5,mod=998244353;
int n=1e6;
ll f[N];
int main(){
ios::sync_with_stdio(0);cin.tie(0);
f[1]=0,f[2]=0,f[3]=2;
ll sum=8;
for(int i=4;i<=n;++i){
f[i]=(1ll*(i-2)*(i+1)/2+sum)%mod;
sum=(sum+f[i]*(i+1))%mod;
}
for(int i=4;i<=n;++i)f[i]=(f[i]+f[i-1])%mod;
int T;
cin>>T;
while(T--)cin>>n,cout<<(n-1+f[n-1])%mod<<'\n';
}
posted @   EssnSlaryt  阅读(404)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示