zoukankan      html  css  js  c++  java
  • P2261 [CQOI2007]余数求和

    传送门

    O(n) 算法可以60分,不用讲了吧...

    考虑怎么加快速度

    首先在不用“%”的情况下求余数应该懂吧

    a%b = a - int(a/b) * b

    int() 是向下取整的意思

    那么题目要求 k%1 + k%2 + ... + k%n

    就等于 k-int(k/1)*1 + k-int(k/2)*2 + ... + k-int(k/n)*n

    整理一下

    = k*n - (int(k/1)*1 + int(k/2)*2 + ... + int(k/n)*n)

    然后我们发现 有一些 int(k/i) 是相等的

    所以可以和在一起计算

    不同的 int(k/i) 大概有 sqrt(k) 种

    讲一下怎么找 i:

    (以下除后都向下取整)

    显然如果 k%i = 0 ,那么 k/(i+1) 肯定不等于 k/i;如果 k%(i-1)=0,那么 k/i 也肯定不等于 k/(i-1)

    所以一个区间的左端点就是 k%i = 0 时的 i+1 ,右端点就是下一个 k%i'=0 的 i'

    考虑怎么求 i' ,显然如果k%i=0,那么 i 就是 k 的一个因子,可以O(sqrt(k)) 找因子;

    还有一种比较好的方法:如果 k%i' = 0 那么 k = q*i' (q为正整数),所以 q = k/i'

    因为k/i' = int(k/ (i+1) ),所以 q=int(k/ (i+1) ),所以 i' = k/q = k/int(k/ (i+1) )

    具体实现还是看代码吧

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    long long n,m,ans;
    int main()
    {
        cin>>n>>m;
        ans=n*m;
        for(long long l=1,r;l<=n;l=r+1)
        //l,r表示对于任意 l<=i<=r,int(k/i)都相等
        {
            if(m/l) r=min(m/(m/l),n);
            else r=n;
            //求出r的大小
            ans-=(m/l)* (r-l+1)*(r+l)/2;
            //(r-l+1)*(r-l)/2 就等于 l+ (l+1) + ... + r 的和
        }
        cout<<ans;
        return 0;
    }    
  • 相关阅读:
    arcgis pro加载其他数据
    ArcGIS Pro运行Python脚本
    获得ArcGIS Pro的版本
    ArcGIS Pro使用键盘控制地图平移
    ArcGIS Pro添加注记工具
    ArcGIS Pro二次开发添加网络图层
    ArcGIS Pro放大缩小按钮
    ArcGIS Pro做一个矩形选择按钮
    ArcGIS Pro获得一个图层的样式
    ArcGIS Pro二次开发闪烁对象
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9605461.html
Copyright © 2011-2022 走看看