51nod1584:加权约数和(数论+线性筛)

来源:互联网 发布:黑马程序员html 编辑:程序博客网 时间:2024/05/29 18:42

离退役不远了,我依然很菜很菜,所以以后博客不再面向对象了,只为自己看懂。
题面

题意:求

i=1nj=1nmax(i,j)σ1(ij)

其中σ1(x)为x的约数和。

分类讨论

2i=1nj=1iiσ1(ij)i=1niσ1(i2)

考虑

i=1nj=1iiσ1(ij)

由kscla的数表,有
=i=1nij=1ia|ib|jaj/b[(a,b)=1]

先枚举a,到i,到b,到j,在把中括号用μ换,
=d=1nμ(d)d2i=1ndi2a=1nidaj=1aib=1aijb

设右半部分为f(nd),有
=d=1nμ(d)d2f(nd)

考虑f,有
f(x)=n=1xni=1nσ21(i)

根据杜教筛的柿子和套路,将f差分,设为g,有
ans(n)=d=1ni|di2μ(i)f(di)

复杂度nln(n)。
这是Kscla的博客,两篇都有错,对着看就好了。
这个T了,也懒得调了。

#include <iostream>#include <fstream>#include <algorithm>#include <cmath>#include <ctime>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;#define mmst(a, b) memset(a, b, sizeof(a))#define mmcp(a, b) memcpy(a, b, sizeof(b))typedef long long LL;const int N=1001000,nn=1000000;LL mo=1e9+7;int T,n;LL prime[N],num,u[N],f[N],miu[N];LL g[N],h[N],p[N];int ans[N],c[N],hh[N];bool b[N];void read(int &hy){    hy=0;    char cc=getchar();    while(cc<'0'||cc>'9')    cc=getchar();    while(cc>='0'&&cc<='9')    {        hy=(hy<<3)+(hy<<1)+cc-'0';        cc=getchar();    }}int main(){    p[1]=miu[1]=u[1]=f[1]=1;    for(int i=2;i<=nn;i++)    {        if(!b[i])        {            prime[++num]=i;            u[i]=i;            miu[i]=-1;            f[i]=i+1;            p[i]=((LL)i*i%mo+i+1)%mo;        }        for(int j=1;j<=num&&prime[j]*i<=nn;j++)        {            LL pj=prime[j];            int ipj=i*pj;            b[ipj]=1;            if(i%pj==0)            {                u[ipj]=u[i]*pj;                f[ipj]=(f[i]+f[i/u[i]]*u[i*pj])%mo;                p[ipj]=(p[i]+p[i/u[i]]*(pj+1)%mo*u[ipj]%mo*u[i]%mo)%mo;                miu[ipj]=0;                break;            }            f[ipj]=f[i]*f[pj]%mo;            p[ipj]=p[i]*p[pj]%mo;            u[ipj]=pj;            miu[ipj]=-miu[i];        }    }    for(int i=1;i<=nn;i++)    p[i]=p[i]*i%mo;    for(int i=1;i<=nn;i++)    p[i]=(p[i]+p[i-1])%mo;    for(int i=1;i<=nn;i++)    g[i]=(g[i-1]+f[i])%mo;    for(int i=1;i<=nn;i++)    h[i]=g[i]*i%mo*f[i]%mo;    for(int i=1;i<=nn;i++)    miu[i]=(miu[i]*i*i%mo+mo)%mo;    for(int i=1;i<=nn;i++)    c[i]=(int)miu[i];    for(int i=1;i<=nn;i++)    hh[i]=(int)h[i];    for(int i=1;i<=nn;i++)    for(int k=i;k<=nn;k+=i)    ans[k]=(ans[k]+(LL)hh[k/i]*c[i]%mo)%mo;    for(int i=1;i<=nn;i++)    ans[i]=(ans[i-1]+ans[i])%mo;    scanf("%d",&T);    for(int i=1;i<=T;i++)    {        read(n);        int tu=(2*ans[n]%mo-p[n]+mo)%mo;        printf("Case #%d: %d\n",i,tu);    }    return 0;}

这里写图片描述

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 啤酒的价格 白酒好还是啤酒好 夜啤酒 啤酒猪蹄 啤酒菜 汉斯啤酒 啤酒销量 天目湖啤酒 5.0啤酒 黑狮啤酒 啤酒价钱 酿造啤酒 汉斯啤酒价格 牙套钢丝扎嘴 扎嘴 骆驼吃仙人掌不扎嘴吗 散罕坝 扎基 扎壶图片 凉水壶 扎多音字组词 扎多音字 扎心语录10个字以内 扎多音字组词和拼音 扎字多音字组词 扎字拼音 扎字开头的成语 扎字五笔怎么打字五笔 扎的多音字 扎的多音字组词和拼音 扎心的话八个字的 扎心短句10字内 多音字扎的读音和组词 扎是多音字吗 扎的组词多音字组词语 扎的多音字组词 扎的多音字组词三个音 扎职2国语中文字 扎的多音字组词和拼音怎么写 扎实 五个扎实