本文主要是介绍bzoj4176 Lucas 的数论,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
======∑i=1n∑j=1nf(ij)∑i=1n∑j=1n∑d=1n2[dgcd(i,d)|j]∑i=1n∑d=1n2⌊n∗gcd(i,d)d⌋∑d=1n∑i=1⌊nd⌋∑j=1⌊n2d⌋⌊nj⌋e(gcd(i,j))∑d=1n∑i=1⌊nd⌋∑j=1n⌊nj⌋∑x|gcd(i,j)μ(x)∑x=1nμ(x)∑d=1n⌊ndx⌋∑j=1⌊nx⌋⌊njx⌋∑x=1nμ(x)(∑j=1⌊nx⌋⌊njx⌋)2
对后面的部分进行下底函数分块,一段 μ(x) 的和用杜教筛求出。
#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn=3000000,p=1000007,mod=1000000007,oo=0x3f3f3f3f;
struct hash_table
{int fir[p+10],ne[maxn],val[maxn],ans[maxn],tot;int find(int n){for (int i=fir[n%p];i;i=ne[i])if (val[i]==n) return ans[i];return oo;}void ins(int n,int x){int y=n%p;tot++;ne[tot]=fir[y];fir[y]=tot;val[tot]=n;ans[tot]=x;}
}h;
int inc(int x,int y)
{x+=y;return x>=mod?x-mod:x;
}
int dec(int x,int y)
{x-=y;return x<0?x+mod:x;
}
int summu(int n)
{if (!n) return 0;int ret=h.find(n);if (ret!=oo) return ret;ret=1;for (int i=2,j;i<=n;i=j+1){j=n/(n/i);ret-=(j-i+1)*summu(n/i);}h.ins(n,ret);return ret;
}
int sumdiv(int n)
{int ret=0;for (int i=1,j;i<=n;i=j+1){j=n/(n/i);ret=inc(ret,(LL)(j-i+1)*(n/i)%mod);}return ret;
}
int main()
{int n,x,y,ans=0;scanf("%d",&n);//n=1000000000;for (int i=1,j;i<=n;i=j+1){j=n/(n/i);x=dec(summu(j),summu(i-1));y=sumdiv(n/i);ans=inc(ans,(LL)x*y%mod*y%mod);}printf("%d\n",ans);
}
这篇关于bzoj4176 Lucas 的数论的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!