51nod 1056

n<=10000000000

然后欧拉函数的前缀和可以用莫比乌斯函数的前缀和快速求,注意各种取模

#include<cstdio>
typedef long long i64;
const int N=20000000,P=1844677,M=1000000007,I2=(M+1)/2;
int ps[N/5],pp=0;
bool isnp[N+5];
int ms[N+5],phs[N+5];
i64 xs[P];
int ys[P];
int f(i64 n){
    if(n<=N)return ms[n];
    int w=n%P;
    while(xs[w]){
        if(xs[w]==n)return ys[w];
        w+=1237;
        if(w>=P)w-=P;
    }
    xs[w]=n;
    i64 s=0;
    for(i64 i=2,j;i<=n;i=j+1){
        j=n/(n/i);
        s+=(j-i+1)*f(n/i);
    }
    return ys[w]=1-s;
}
int sum_phi(i64 n){
    if(n<=N)return phs[n];
    i64 ans=0;
    for(i64 i=1,j;i<=n;i=j+1){
        i64 k=n/i;
        j=n/k;
        k%=M;
        ans=(ans+k*k%M*(f(j)-f(i-1)))%M;
    }
    ans=(ans+1)*I2%M;
    return ans;
}
int main(){
    ms[1]=phs[1]=1;
    for(int i=2;i<=N;i++){
        if(!isnp[i])ms[ps[pp++]=i]=-1,phs[i]=i-1;
        for(int j=0;j<pp&&i*ps[j]<=N;j++){
            isnp[i*ps[j]]=1;
            if(i%ps[j])ms[i*ps[j]]=-ms[i],phs[i*ps[j]]=phs[i]*(ps[j]-1);
            else{
                phs[i*ps[j]]=phs[i]*ps[j];
                break;
            }
        }
    }
    for(int i=1;i<=N;i++)ms[i]+=ms[i-1];
    for(int i=1;i<=N;i++)(phs[i]+=phs[i-1])%=M;
    i64 n,ans=0;
    scanf("%lld",&n);
    for(i64 i=1,j=1,k;i<=n;i=j+1){
        k=n/i;
        j=n/k;
        k%=M;
        ans=(ans+k*(k+1)%M*(sum_phi(j)-sum_phi(i-1)))%M;
    }
    n%=M;
    ans=(ans-n*(n+1)%M*I2)%M;
    printf("%lld",(ans+M)%M);
    return 0;
}
时间: 2024-10-20 14:17:33

51nod 1056的相关文章

51nod 1201 整数划分(dp)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1201 题解:显然是一道dp,不妨设dp[i][j]表示数字i分成j个一共有几种分法. 那么转移方程式为: dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] 表示将i - 1划分为j个数,然后j个数都+1 还是不重复,将i - 1划分为j - 1个数,然后j - 1个数都+1,再加上1这个数. 然后就是j的范围要知道1+2+

1056. 组合数的和

1056. 组合数的和(15) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 给定N个非0的个位数字,用其中任意2个数字都可以组合成1个2位的数字.要求所有可能组合出来的2位数字的和.例如给定2.5.8,则可以组合出:25.28.52.58.82.85,它们的和为330. 输入格式: 输入在一行中先给出N(1<N<10),随后是N个不同的非0个位数字.数字间以空格分隔. 输出格式: 输出所有可能组合出来的2

51nod 1138 连续整数的和(数学)

题目描述: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1138 给出一个正整数N,将N写为若干个连续数字和的形式(长度 >= 2).例如N = 15,可以写为1 + 2 + 3 + 4 + 5,也可以写为4 + 5 + 6,或7 + 8.如果不能写为若干个连续整数的和,则输出No Solution. Input 输入1个数N(3 <= N <= 10^9). OutPut 输出连续整数中的第1个数,如果有多

51nod 1463 找朋友(线段树+离线处理)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序,因为k一共最多只有10个,所有在该区间内的B数组,每次枚举K值,通过这样的方式来得到另外一个B值.但是这样得到的B值它在B数组中的位置必须在当前数的左边.如下图:(j为当前数在B数组中的位置,pos为计算得到的另一个B值在数组中的位置) 这两个数的和记录在pos中,这里pos的位置必须在j的左边,假

51nod 1437

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1437 1437 迈克步 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 有n只熊.他们站成一排队伍,从左到右依次1到n编号.第i只熊的高度是ai. 一组熊指的队伍中连续的一个子段.组的大小就是熊的数目.而组的力量就是这一组熊中最小的高度. 迈克想知道对于所有的组大小为x(1 ≤ x ≤ n

51nod 1272 思维/线段树

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1272 1272 最大距离 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 给出一个长度为N的整数数组A,对于每一个数组元素,如果他后面存在大于等于该元素的数,则这两个数可以组成一对.每个元素和自己也可以组成一对.例如:{5, 3, 6, 3, 4, 2},可以组成11对,如下(数字为下标):

51nod 1406 位运算/dp

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1406 1406 与查询 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 有n个整数.输出他之中和x相与之后结果为x的有多少个.x从0到1,000,000 Input 第一行输入一个整数n.(1<=n<=1,000,000). 第二行有n个整数a[0],a[1],a[2],...a[n-1

51nod 1307 绳子与重物(并查集水了一发)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1307 题意: 思路: 可以直接二分答案,然后dfs. 因为标签是并查集,所以我考虑了一下并查集,利用并查集不断向上回溯加负重,居然过了,只能说数据有点水. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #incl

hdu6153 A Secret CCPC网络赛 51nod 1277 KMP

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6153 题意: 给出两个字符串S1,S2,求S2的所有后缀在S1中出现的次数与其长度的乘积之和. 思路: CCPC网络赛题解: https://post.icpc-camp.org/d/714-ccpc-2017 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1277   是一样的 将s1,s2翻转,转化为求前缀在s1中出