卧薪尝胆,厚积薄发。
One?One!
Date: Fri Mar 22 16:47:36 CST 2019 In Category: NoCategory

Description:

给出 $s_0$ ,用如下方式生成数列 $d_i$ : $$ d_i=\lfloor\frac{s_i}{1024}\rfloor\bmod 10,s_i=(747796405s_{i-1}-1403630843) $$ 设 $n$ 的十进制表示为 $d_0,$ $d_1,\dots,d_{l-1},d_l$ , $oneness(k)$ 表示 $k$ 的所有大于 $1$ 的约数中十进制下全是 $1$ 的约数个数,给出 $l$ ,求: $$ \sum_{i=1}^noneness(i) $$ $1\leqslant l\leqslant 250000$

Solution:

$$ \sum_{i=1}^noneness(i)=\sum_{i=2}^l\bigg\lfloor\frac n{\underbrace{11\cdots 1}_{i个1}}\bigg\rfloor=\sum_{i=2}^l\bigg\lfloor\frac{9n}{10^l-1}\bigg\rfloor $$
设 $N=9n=x\times 10^d+y(y<10^d)$ ,那么: $$ \bigg\lfloor\frac N{10^l-1}\bigg\rfloor=\bigg\lfloor\frac {x\times 10^l}{10^l-1}+\frac y{10^l-1}\bigg\rfloor=\bigg\lfloor\frac{x\times (10^l-1)+x}{10^l-1}+\frac y{10^l-1}\bigg\rfloor=\bigg\lfloor x+\frac x{10^l-1}+\frac y{10^l-1}\bigg\rfloor $$ 然后我们考虑计算贡献,会发现每次相当于是把 $N$ 十进制下右移了 $l$ 位再计算,我们先只考虑 $x$ 那部分贡献,那么也就是第 $i$ 位对第 $j$ 位的贡献是 $i-j$ 不为 $1$ 的约数个数,也就是 $b[j]=\sum_{i=j}^na[i]\times (\sigma(i-j)-1)$ 这其实是一个卷积,可以用 $FFT$ 加速计算。
最后考虑 $y$ 的贡献,会发现其实是把 $N$ 每 $l$ 分一段加在一起,因为最后有一个下取整而且数据近似随机,我们可以只把高 $15$ 位拿出来暴力计算。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
using namespace std;
inline int rd()
{
register int res = 0,f = 1;register char c = getchar();
while(!isdigit(c)){if(c == '-')f = -1;c = getchar();}
while(isdigit(c))res = (res << 1) + (res << 3) + c - '0',c = getchar();
return res * f;
}
int n;
#define MAXN 1000010
unsigned int s[MAXN];
int d[MAXN];
int v1[MAXN];
int sigma[MAXN];
int res[MAXN];
int ans[MAXN];
int ww[MAXN << 1],*g = ww + MAXN;
int rev[MAXN];
#define P 998244353
int power(int a,int b)
{
int res = 1;
for(;b > 0;b = b >> 1,a = 1ll * a * a % P)if(b & 1)res = 1ll * res * a % P;
return res;
}
int init(int n)
{
int l = 0,len = 1;
for(;len <= n;len = len << 1)++l;
for(int i = 0;i < len;++i)rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (l - 1));
g[0] = g[-len] = 1;g[1] = g[1 - len] = power(3,(P - 1) / len);
for(int i = 2;i < len;++i)g[i] = g[i - len] = 1ll * g[i - 1] * g[1] % P;
return len;
}
void NTT(int f[],int l,int type)
{
for(int i = 0;i < l;++i)
{
if(i < rev[i])swap(f[i],f[rev[i]]);
}
for(int i = 2;i <= l;i = i << 1)
{
int wn = g[type * l / i];
for(int j = 0;j < l;j += i)
{
int w = 1;
for(int k = j;k < j + i / 2;++k)
{
int u = f[k],t = 1ll * w * f[k + i / 2] % P;
f[k] = (u + t) % P;
f[k + i / 2] = (u - t + P) % P;
w = 1ll * w * wn % P;
}
}
}
if(type == -1)
{
int ni = power(l,P - 2);
for(int i = 0;i < l;++i)f[i] = 1ll * f[i] * ni % P;
}
return;
}
int t[MAXN];
#define L 15
long long pow10[20];
int main()
{
scanf("%d",&n);
scanf("%d",&s[0]);
for(int i = 1;i <= n;++i)s[i] = (747796405ll * s[i - 1] - 1403630843) % (1ll << 32);
for(int i = 0;i < n;++i)d[i] = (s[i] / 1024) % 10;
for(int i = n;i >= 1;--i)d[i] = d[i - 1];
for(int i = 1,j = n;i < j;++i,--j)swap(d[i],d[j]);
d[0] = 0;
for(int i = n;i >= 1;--i)d[i] = d[i] * 9;
for(int i = 1;i <= n;++i)d[i + 1] += d[i] / 10,d[i] %= 10;
if(d[n + 1])++n;
for(int i = 2;i <= n;++i)for(int j = i;j <= n;j += i)++sigma[j];
sigma[0] = 1;
for(int i = 0;i <= n;++i)v1[i] = d[i];
for(int i = 0,j = n;i < j;++i,--j)swap(v1[i],v1[j]);
int l = init(n * 2);
NTT(sigma,l,1);NTT(v1,l,1);
for(int i = 0;i < l;++i)t[i] = 1ll * sigma[i] * v1[i] % P;
NTT(sigma,l,-1);NTT(v1,l,-1);NTT(t,l,-1);
for(int k = 1;k <= n - 2;++k)res[k] += t[n - k];
for(int k = 1;k <= n - 2;++k)res[k] -= d[k];
int cur = 100;
pow10[0] = 1;
for(int i = 1;i <= L;++i)pow10[i] = 1ll * pow10[i - 1] * 10;
for(int i = 2;i <= n;++i)
{
int l = min(L,i);
long long ss = 0;
for(int k = i;k < n + i;k += i)for(int j = 1;j <= l;++j)ss += 1ll * d[k - j + 1] * pow10[l - j];
res[1] += ss / (pow10[l] - 1);
cur = cur * 10;
}
for(int i = 1;i <= n;++i)
{
int val = res[i];
if(val < 0)
{
val = -val;
int cnt = val / 10;
res[i + 1] -= val;
res[i] += val * 10;
while(res[i] < 0)res[i] += 10,res[i + 1]--;
}
}
for(int i = 1;i <= n;++i)res[i + 1] += res[i] / 10,res[i] %= 10;
while(res[n + 1])++n,res[n + 1] += res[n] / 10,res[n] %= 10;
while(res[n] == 0)--n;
for(int i = n;i >= 1;--i)cout << res[i];cout << endl;
return 0;
}

Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡