zoukankan      html  css  js  c++  java
  • hdu5608:function

    $n^2-3n+2=sum_{d|i}f(i)$,问$f(i)$前$n$项和。

    方法一:直接切入!

    $S(n)=sum_{i=1}^{n}f(i)=sum_{i=1}^{n}(i^2-3i+2-sum_{d|i,d<i}f(d))=sum_{i=1}^{n}(i^2-3i+2)-sum_{i=1}^{n}sum_{d|i,d<i}f(d)=frac{n(n+1)(2n+1)}{6}-frac{3n(n+1)}{2}+2n-sum_{k=2}^{n}sum_{d=1}^{left lfloor frac{n}{k} ight floor}f(d)$

    且不管他是不是什么积性函数了,符合杜教筛形式直接算!!

    方法二:仔细乱搞

    这一看就是反演形式,那就令$g(n)=n^2-3n+2$,反演得

    $f(n)=sum_{d|n}mu (d)g(frac{n}{d})=sum_{d|n}mu(d)(frac{n}{d})^2-3sum_{d|n}mu(d)frac{n}{d}+2sum_{d|n}mu(d)=h(n)-3varphi (n)+2[n=1]$

    现在需要知道这三坨东西的前缀和。其中欧拉函数之前写过了,[n=1]的话。。然后就剩个$h(n)$也就是$sum_{d|n}mu(d)(frac{n}{d})^2$。

    $sum_{i=1}^{n}sum_{d|i}mu (d)(frac{i}{d})^2=sum_{k=1}^{n}k^2sum_{d=1}^{left lfloor frac{n}{k} ight floor}mu (d)$。

    莫比乌斯的前缀和就可以杜教筛啦!!

    方法一是便捷的方式,但方法二是常用的套路,各有千秋。代码方法一。

     1 #include<string.h>
     2 #include<stdlib.h>
     3 #include<stdio.h>
     4 #include<math.h>
     5 //#include<assert.h>
     6 #include<algorithm> 
     7 //#include<iostream>
     8 //#include<bitset>
     9 using namespace std;
    10 
    11 int T,n,pr;
    12 #define maxn 1000011
    13 #define LL long long
    14 const int mod=1e9+7;
    15 LL s[maxn],f[maxn];
    16 void pre(int n)
    17 {
    18     for (int i=1;i<=n;i++)
    19     {
    20         f[i]+=1ll*i*i-3*i+2;
    21         for (int j=i+i;j<=n;j+=i) f[j]-=f[i];
    22     }
    23     for (int i=1;i<=n;i++) s[i]=((s[i-1]+f[i])%mod+mod)%mod;
    24 }
    25 
    26 struct Edge{int to,v,next;};
    27 #define maxh 1000007
    28 struct Hash
    29 {
    30     int first[maxh],le; Edge edge[maxn];
    31     Hash() {le=2;}
    32     void insert(int y,int v)
    33     {int x=y%maxh; Edge &e=edge[le]; e.to=y; e.v=v; e.next=first[x]; first[x]=le++;}
    34     int find(int y)
    35     {int x=y%maxh; for (int i=first[x];i;i=edge[i].next) if (edge[i].to==y) return edge[i].v; return -1;}
    36 }h;
    37 
    38 int six=(mod+1)/6,two=(mod+1)>>1;
    39 int calc(int n)
    40 {
    41     if (n<=pr) return s[n];
    42     int tmp=h.find(n); if (tmp!=-1) return tmp;
    43     int tot=0;
    44     for (int i=2,last;i<=n;i=last+1)
    45     {
    46         last=n/(n/i);
    47         tot+=(last-i+1)*1ll*calc(n/i)%mod;
    48         tot-=tot>=mod?mod:0;
    49     }
    50     int ans=((six*1ll*n%mod*(n+1)%mod*(2*n+1)%mod-two*3ll*n%mod*(n+1)%mod+2*n)%mod+mod)%mod;
    51     ans=(ans-tot+mod)%mod;
    52     h.insert(n,ans);
    53     return ans;
    54 }
    55 
    56 int main()
    57 {
    58     pre(pr=1000000);
    59     scanf("%d",&T);
    60     while (T--) scanf("%d",&n),printf("%d
    ",calc(n));
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    LeetCode刷题记录2020-10-07之动态规划入门!!!线性DP(二)
    LeetCode刷题记录2020-10-06之动态规划入门!!!线性DP
    LeetCode刷题记录2020-10-05之Double Pointer!!!
    Python核心编程之属性查找过程!
    Python核心编程之元类!
    Python配置文件的导入方式和源码分析!
    大数据架构入门之二:埋点数据流程
    day46 css第二part
    day44天 HTTP协议 和前端html协议
    day39 视图 触发器 事务 存储过程 函数 流程控制 索引与慢查询优化
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8318522.html
Copyright © 2011-2022 走看看