Ans:2992480851924313898
注意到
σ
是积性函数,所以我们考虑唯一分解,然后每一部分形如
apii
的贡献是
1+ai+...+apii
,都可以预处理是否是
2017
的倍数.这里要特别处理
pi=1
的部分,因为数比较多。我们注意到
pi=1
时合法当且仅当
ai mod 2017=2016
,所以用筛法就行了。剩下的容斥。注意到每个预处理出来的数的基数都不一样(如果在1e12的级别就有一样的了。。。),且没有一个数可以拥有三个预处理出来的数的乘积的因子。所以我们暴力枚举一个还是两个进行容斥。注意积性函数并非完全积性函数,所以我们还要去掉两个相同的数的乘积。最后,一开始的筛法的第一个数定位我们可以用exgcd。
15s左右,我也不知道复杂度。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll n = 1e11, k = 2017;
bool B[50000010], B2[5000010];
struct node
{
ll x, y;
node() {} node(ll _, ll __) {x = _, y = __;}
bool operator < (const node& X) const {return x < X.x;}
} L[50000010];
ll t = 0, ans = 0;
void exgcd(ll a, ll& x, ll b, ll& y)
{
if(!b) x = 1, y = 0; else exgcd(b, y, a % b, x), y -= a / b * x;
}
ll calc(ll a)
{
ll x, y;
exgcd(k, x, a, y);
return (x % a + a) % a;
}
ll calc2(ll a) {return (a + n / a * a) * (n / a);}
ll S(ll a) {return a * (a + 1) / 2;}
int main()
{
ll tmp1 = n / k, tmp2 = sqrt(n);
for(int i = 2; i <= tmp2; i++) {
if(!B2[i]) for(int j = i + i; j <= tmp2; j += i) B2[j] = 1;
if(i % k) for(int j = calc(i); j <= tmp1; j += i) if(j * k != i + 1) B[j] = 1;
}
for(int i = 1; i <= tmp1; i++) if(!B[i]) L[++t] = node(k * i - 1, k * i - 1);
for(ll i = 2; i <= tmp2; i++) if(!B2[i] && i % k != k - 1)
for(ll j = i * i, s = 1 + i; j <= n; j *= i)
if((s += j) % k == 0) L[++t] = node(j, i);
printf("%lld\n", t);
sort(L + 1, L + t + 1);
for(int i = 1; i <= t; i++) ans += L[i].x * S(n / L[i].x);
for(int i = 1; i <= t; i++)
if(L[i].x * L[i].y <= n) ans -= L[i].x * L[i].y * S(n / L[i].x / L[i].y);
for(int i = 1; i <= t; i++)
for(int j = i + 1; j <= t; j++)
if(L[i].x > n / L[j].x) break; else ans -= L[i].x * L[j].x * S(n / L[i].x / L[j].x);
printf("%lld\n", ans);
return 0;
}