• HDU5608 function


    解:显然f那个式子可以反演一波,然后再推一波,最后出来了这个......

    其中M是莫比乌斯函数的前缀和。虽然看起来能算...感觉很毒瘤,复杂度也不会。

    正解:杜教筛的套路是对一个卷函数求前缀和,然后拆开。

    于是我们直接对(i2 - 3i + 2)求前缀和,之后就是一个很普通的杜教筛式子了......

    如何预处理f?利用反演式子,考虑每个(i2 - 3i + 2)会对哪些f有所贡献即可。复杂度调和级数。

    注意long long和取模...我全程爆炸调了一晚上。

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <cstring>
     4 #include <map>
     5 
     6 typedef long long LL;
     7 const int N = 1000010, T = 1000008;
     8 const LL MO = 1e9 + 7, inv6 = 166666668, inv2 = 500000004, INF = 0x7f7f7f7f7f7f7f7fll;
     9 
    10 int miu[N], p[N], top;
    11 LL F[N], n;
    12 std::map<LL, LL> F2;
    13 bool vis[N];
    14 
    15 inline LL qpow(LL a, LL b) {
    16     LL ans = 1;
    17     while(b) {
    18         if(b & 1) ans = ans * a % MO;
    19         a = a * a % MO;
    20         b = b >> 1;
    21     }
    22     return ans;
    23 }
    24 
    25 inline LL G(LL x) {
    26     x %= MO;
    27     return (((x * 2 + 1) % MO) * inv6 % MO * x % MO * ((x + 1) % MO) % MO -
    28     ((x + 1) % MO) * inv2 % MO * x % MO * 3 % MO + x * 2 % MO) % MO;
    29 }
    30 
    31 inline LL g(LL x) {
    32     x %= MO;
    33     return (x * x % MO - 3 * x % MO + 2 + MO) % MO;
    34 }
    35 
    36 inline void prework() {
    37     /// get miu
    38     miu[1] = 1;
    39     for(int i = 2; i <= T; i++) {
    40         if(!vis[i]) {
    41             p[++top] = i;
    42             miu[i] = -1;
    43         }
    44         for(int j = 1; j <= top && i * p[j] <= T; j++) {
    45             vis[i * p[j]] = 1;
    46             if(i % p[j] == 0) break;
    47             miu[i * p[j]] = -miu[i];
    48         }
    49     }
    50     /// getF
    51     for(int i = 1; i <= T; i++) {
    52         LL t = g(i);
    53         for(int j = 1; i * j <= T; j++) {
    54             F[i * j] += t * miu[j] % MO;
    55             F[i * j] = (F[i * j] % MO + MO) % MO;
    56         }
    57     }
    58     for(int i = 1; i <= T; i++) {
    59         F[i] = (F[i] + F[i - 1]) % MO;
    60     }
    61     return;
    62 }
    63 
    64 LL solve(LL x) {
    65     if(x <= 0) return 0;
    66     if(x <= T) return F[x];
    67     if(F2.count(x)) return F2[x];
    68     LL ans = G(x);
    69     for(LL i = 2, j; i <= x; i = j + 1) {
    70         j = x / (x / i);
    71         ans -= solve(x / i) * (j - i + 1) % MO;
    72         ans = (ans % MO + MO) % MO;
    73     }
    74     return F2[x] = ans;
    75 }
    76 
    77 int main() {
    78     int q;
    79     scanf("%d", &q);
    80     prework();
    81     //printf("q = %d 
    ", q);
    82     for(int i = 1; i <= q; i++) {
    83         //printf("i = %d q = %d 
    ", i, q);
    84         scanf("%lld", &n);
    85         printf("%lld
    ", solve(n));
    86     }
    87     return 0;
    88 }
    AC代码
  • 相关阅读:
    gradle3.0新命令
    Android Studio项目生成Jar包
    《图解HTTP》读书笔记
    Java实现多继承
    Unity3d和Android之间互相调用
    《Gradle权威指南》--Android Gradle NDK支持
    《Gradle权威指南》--Android Gradle测试
    《Gradle权威指南》--Android Gradle多渠道构建
    adb命令大全
    SparseArray源码解析
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10440616.html
Copyright © 2020-2023  润新知