- 生成函数模板题
首先对于要求为 倍数的要求可以构造生成函数:
由定理可得:
对于另一种要求及
然后我们把这些项全部乘起来得:
答案就是上面这个多项式 的系数之和:
由于 以及优秀的模数直接用 计算即可
#include <bits/stdc++.h>
#define int long long
#define For(i,a,b) for ( register int i=(a);i<=(b);i++ )
#define Dow(i,b,a) for ( int i=(b);i>=(a);i-- )
#define GO(i,x) for ( int i=head[x];i;i=e[i].nex )
#define mem(x,s) memset(x,s,sizeof(x))
#define cpy(x,s) memcpy(x,s,sizeof(x))
#define YES return puts("YES"),0
#define NO return puts("NO"),0
#define GG return puts("-1"),0
#define pb push_back
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
const int N=6e5+5;
const int mo=998244353;
const int G=3;
int n,m,l1,l2,l3,l4,a[N],b[N],c[N],d[N],ans[N];
int r[N],lim=1,II=0;
char s[N];
inline int ksm(int x,int y)
{
int ret=1;
while(y)
{
if(y&1ll) ret=ret*x%mo;
x=x*x%mo;
y>>=1ll;
}
return ret%mo;
}
inline void NTT(int *a,int inv)
{
For(i,0,lim-1) if(i<r[i]) swap(a[i],a[r[i]]);
for ( register int mid=1;mid<lim;mid<<=1ll)
{
int tmp=ksm(G,(mo-1)/(mid*2ll));
if(inv) tmp=ksm(tmp,mo-2);
for ( register int i=0;i<lim;i+=mid*2ll )
{
int w=1ll;
for ( register int j=0;j<mid;j++,w=w*tmp%mo )
{
int x=a[i+j];
int y=w*a[i+j+mid]%mo;
a[i+j]=(x+y)%mo;
a[i+j+mid]=(x-y+mo)%mo;
}
}
}
if(inv)
For(i,0,lim-1) a[i]=a[i]*II%mo;
}
inline void MUL(int *f,int *g)
{
NTT(f,0),NTT(g,0);
// puts("orz");
For(i,0,lim-1) f[i]=f[i]*g[i]%mo;
NTT(f,1);
int tmp=0;
For(i,0,lim-1)
{
a[i]+=tmp;
tmp=a[i]/10ll;
a[i]%=10ll;
if(a[i]) l1=i+1;
}
}
signed main()
{
// freopen("A.in","r",stdin);
// freopen("A.out","w",stdout);
scanf("%s",s);
int len=strlen(s);
int l=0;
lim=1ll;
while(lim<=400000) lim<<=1ll,l++;
II=ksm(lim,mo-2);
For(i,0,lim-1) r[i]=r[i>>1ll]>>1ll|((i&1ll)<<(l-1));
reverse(s,s+len);
For(i,0,len-1) a[i]=s[i]-48;
int x=1;
For(i,0,len)
{
a[i]=a[i]+x;
x=a[i]/10ll;
a[i]%=10ll;
if(a[i]) l1=i+1;
}
x=1;
For(i,0,l1-1)
{
b[i]=a[i]+x;
x=b[i]/10ll;
b[i]%=10ll;
if(b[i]) l2=i+1;
}
x=1;
For(i,0,l2-1)
{
c[i]=b[i]+x;
x=c[i]/10ll;
c[i]%=10ll;
if(c[i]) l3=i+1;
}
x=1;
For(i,0,l3-1)
{
d[i]=c[i]+x;
x=d[i]/10ll;
d[i]%=10ll;
if(d[i]) l4=i+1;
}
MUL(a,b);
MUL(a,c);
MUL(a,d);
int P=0,ll=0;
Dow(i,l1-1,0)
{
P=P*10ll+a[i];
ans[i]=P/24ll;
P%=24ll;
if(ans[i]&&!ll) ll=i+1;
}
if(!ll) ll=1;
Dow(i,ll-1,0) printf("%lld",ans[i]);
return 0;
}