Educational Codeforces Round 138 D

D. Counting Arrays

我们对于每一个找合法序列是多少显然很麻烦
我们直接找不合法的
显然对于i个位置上 他不能是前面lcm(1,2,3...i-1)的倍数才可以
显然我们这里面 lcm(只能有质因数构成)也就是最小的 不然可能会漏解
不然我们可以通过一直删第一个位置 让他又变成一个合法的序列
所以我们直接对于每一个i找出有多少个数不合法 然后与i-1的方案乘法原理
再用总的方案-不合法方案即可
注意 m就大于mod了 只要出现了m就要注意取模

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
int up(int a,int b){return a<0?a/b:(a+b-1)/b;}
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define pi acos(-1)
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int st[N],primes[N],cnt=0;
void init() {
for(int i = 2 ; i < N ; i ++ ) {
if(!st[i]) primes[cnt ++ ] = i;
for(int j = 0; primes[j] * i < N ; j ++ ) {
st[primes[j] * i] = true;
if(i % primes[j] == 0) break;
}
}
}
int lcm(int a, int b) {
return a * b / __gcd(a, b);
}
int qpow(int a,int k,int p){
int res=1;
while(k){
if(k&1)res=res*a%p;
k>>=1;
a=a%p*a%p;
}
return res;
}
void solve() {
init();
int n,m;cin>>n>>m;
int sum=1,ans=0,lc=1;
for(int i=1;i<=n;i++)(ans+=qpow(m%mod,i,mod))%=mod;
for(int i=1;i<=n;i++){
if(!st[i])lc=lcm(lc,i);
(sum*=(m/lc)%mod)%=mod;
(ans-=sum)%=mod;
(ans+=mod)%=mod;
}
cout<<(ans+mod)%mod<<endl;
}
signed main(){
fast
int t;t=1;//cin>>t;
while(t--) {
solve();
}
return ~~(0^_^0);
}
posted @   ycllz  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示