题意:对于一个数组a来说,如果gcd[a[i], i]==1,那么可以删去第i个元素,i之后的元素向前挪一格。进行若干次操作,可以将数组清空。如果清空数组的方式不唯一,那么称这个数组是模糊的。现给出两个数n和m,来组成一个长度在[1, n]之间的数组,数组的每个值可以取[1, m]。求能组成多少个模糊的数组。
解:显然所有数组都可以通过不停地删除第一个元素来清空,如果一个数组不模糊,那么它就只能通过删除第一个元素清空。这意味着每一个元素都与它的位置不互质,而且删除第一个元素后,它的位置会往前挪一格,因此它还和之前所有数,也就是1-i,都不互质。现在问题变成了对于一个位置i,在[1, m]内,有多少个数和[1, i]所有数都不互质。都不互质比都互质好算多了。不互质意味着它们有相同的因子,也就是这个数包含[1, i]内所有质数最少一次,即范围内所有质数之积及其倍数。3e5内所有质数之积刚好没爆long long,而且超过m其实就没有算的必要了。
代码:

#include <bits/stdc++.h> using namespace std; #define maxx 300005 #define maxn 25 #define maxm 205 #define ll long long #define inf 1000000009 #define mod 998244353 int prime[maxx]={0}; ll mul[maxx]={0}; void init(int n){ for (int i = 2; i <= n; i++){ if (prime[i]) continue; for (int j = i; j <= n/i; j ++) prime[i*j] = 1; } mul[0]=1; for(int i=1;i<=n;i++){ mul[i]=mul[i-1]; if(!prime[i]) mul[i]=mul[i]*i; } } signed main() { // int T; // scanf("%d",&T); // while(T--){ // // } ll n,m; scanf("%lld%lld",&n,&m); init(n); ll res=1,ans=0; for(int i=1;i<=n;i++){ if(mul[i]>m) break; res=(res*((m/mul[i])%mod))%mod; ans=(ans+res)%mod; } ll tot=0,tot1=1; for(int i=1;i<=n;i++){ tot1=(tot1*(m%mod))%mod; tot=(tot1+tot)%mod; } printf("%lld\n",(tot-ans+mod)%mod); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?