题解:CF2039F1 Shohag Loves Counting (Easy Version)
Starriverlight · · 题解
我没有莫比乌斯反演😋
从大到小考虑字段长度,容易发现整个序列的最大值一定在最左侧或最右侧,再往下递归就得出了序列是单谷。
现在问题转化成了,对所有递减序列计数,要求所有前缀的 gcd 不同(即递减),长度为
考虑 dp,设
不妨先忽略 gcd 的限制,直接枚举
考虑算多了什么,也就是说我们从一个
此时还有一些问题,就是如果原来 gcd 是
此时我们只需要在开始转移前缀时不转移给
最后,由于
分析一下复杂度,
::::success[AC code]
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define ull unsigned long long
#define f(i,j,n) for(int i=(j);i<=(n);i++)
#define F(i,n,j) for(int i=(n);i>=(j);i--)
#define rep(v,x) for(auto v:x)
#define per(v,x) for(auto it=(x).rbegin();it!=(x).rend();++it)if (auto v=*it;true)
#define updmax(a,b) a=max(a,b)
#define updmin(a,b) a=min(a,b)
#define updsum(a,b) a=(a+(b))%mod
#define updtim(a,b) a=a*(b)%mod
#define pb push_back
#define arr(x) array<int,x>
#define pri_grt(x) x,vector<x>,greater<x>
using namespace std;
typedef pair<int,int> pii;
namespace fsd{
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXSIZE,stdin),p1==p2)?EOF:*p1++)
const int MAXSIZE=1<<20;
char buf[MAXSIZE],*p1,*p2;
inline int read(){
int ak=0,ioi=1;char c=gc();
while(!isdigit(c)){if(c=='-')ioi=-1;c=gc();}
while(isdigit(c))ak=ak*10+(c^48),c=gc();
return ak*ioi;
}
inline string reads(){
string o="";
char p=gc();
while(p>'z'||p<'a'){p=gc();}
while(p<='z'&&p>='a'){o+=p;p=gc();}
return o;
}
inline char readc(){
char p=gc();
while(!((p<='z'&&p>='a')||(p<='Z'&&p>='A'))){p=gc();}
return p;
}
inline long double readd(){
long double ak=0;int ioi=1;char c=gc();
while(!isdigit(c)){if(c=='-')ioi=-1;c=gc();}
while(isdigit(c))ak*=10,ak+=c-'0',c=gc();
if(c=='.'){
c=gc();
long double q=0.1;
while(isdigit(c))ak+=(c-'0')*q,q*=0.1,c=gc();
}
return ak*ioi;
}
}
using namespace fsd;
#define NXD
const int N=1e5+10;
const int mod=998244353;
int IOI[N*20],*IOIx=IOI,*dp[N];
int m;
void gs(){
m=read();
IOIx=IOI;
f(i,1,m)dp[i]=IOIx,IOIx+=m/i;
for(int *i=IOI;i<IOIx;i++)*i=0;
F(i,m,1){
for(int x=i*2;x<=m;x+=i)for(int y=x,c=0;y<=m;y+=x,c++)updsum(dp[i][y/i-2],dp[x][c]*2);
for(int c=m/i-2;c>=0;c--)updsum(dp[i][c],dp[i][c+1]);
for(int x=i*2;x<=m;x+=i)for(int c=m/x-1,y=(c+1)*x,sm=0;c>=0;y-=x,c--)updsum(sm,dp[x][c]),updsum(dp[i][y/i-1],-sm),updsum(sm,dp[x][c]);
f(c,0,m/i-1)dp[i][c]++;
}
int ans=0;
f(i,1,m)f(c,0,m/i-1)updsum(ans,dp[i][c]);
printf("%lld\n",(ans+mod)%mod);
}
#define XXX
signed main(){
#ifndef XXX
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
#ifdef NXD
int t=0;cin>>t;while(t--)
#endif
gs();
return 0;
}
::::