PE 565

来源:互联网 发布:女鬼桂缘捏脸数据 编辑:程序博客网 时间:2024/04/29 11:27

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;}
0 0
原创粉丝点击