• koishi的数学题


    洛咕

    题意:输入一个整数(n),设(f(x)=sum_{i=1}^n x~mod~i),你需要输出(f(1),f(2)...f(n)).(n<=1e6.)

    因为当(i>x)时,(x~mod~ i=x),这一部分可以直接(O(1))计算.所以先不管.(产生的贡献是(x*(n-x)))

    分析:分析取模的性质/规律的时候有一个常用套路:(x~mod~i=x-lfloor frac{x}{i} floor*i).

    所以设(f[x]=sum_{i=1}^x x-lfloor frac{x}{i} floor*i)

    把前面的(x)提出来,(f[x]=x^2-sum_{i=1}^x lfloor frac{x}{i} floor*i)

    (g[x]=sum_{i=1}^x lfloor frac{x}{i} floor*i),则(f[x]=x^2-g[x])

    来考虑一下如何求(g[x]?)(以下的分析很套路,碰到类似的取模问题,都可以这样找到规律),当(i)不变时,(lfloor frac{x}{i} floor)不等于(lfloor frac{x+1}{i} floor),当且仅当(i)(x+1)的约数.即当(i)(x+1)的约数时,(lfloor frac{x+1}{i} floor=lfloor frac{x}{i} floor+1),则(lfloor frac{x+1}{i} floor*i=lfloor frac{x}{i} floor*i+i).所以(g[x+1]=g[x]+sum[x]),其中(sum[x])表示(x)的约数和.

    综上,预处理出每个数的约数和,这个可以用倍数法在(nlogn)的时间内做到,然后就是线性递推求(g)数组,然后对于每一个(x),(ans=x^2-g[x]+x*(n-x)).

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=1e6+5;
    ll sum[N],g[N];
    int main(){
    	int n=read();
    	for(int i=1;i<=n;++i)
    		for(int j=1;j*i<=n;++j)sum[i*j]+=i;	
    	for(int i=1;i<=n;++i)g[i]=g[i-1]+sum[i];
    	for(int i=1;i<=n;++i)printf("%lld ",1ll*i*i-g[i]+1ll*i*(n-i));	
        return 0;
    }
    
    
  • 相关阅读:
    windows下nginx的安装及使用
    JAVA面试经历
    项目框架搭建
    383. Ransom Note
    Add to List 349. Intersection of Two Arrays
    171. Excel Sheet Column Number
    463. Island Perimeter
    669. Trim a Binary Search Tree
    496. Next Greater Element I
    637. Average of Levels in Binary Tree
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11734330.html
Copyright © 2020-2023  润新知