• 【CQOI 2007】 余数求和


    题目描述

    给出正整数n和k,计算G(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod i表示k除以i的余数。例如G(10, 5)=5 mod 1 + 5 mod 2 + 5 mod 3 + 5 mod 4 + 5 mod 5 …… + 5 mod 10=0+1+2+1+0+5+5+5+5+5=29

    输入输出格式

    输入格式:

    两个整数n k

    输出格式:

    答案

    输入输出样例

    输入样例#1:
    10 5
    输出样例#1: 
    29

    说明

    30%: n,k <= 1000

    60%: n,k <= 10^6

    100% n,k <= 10^9

    ------------------------------------------------------------------------------------------------------------------------

    题外话:考试头一天在lydrainbowcat的书上刚看到这道题,结果弱弱的我就打了一个小小的问号就看下一页了然后考场上就没有然后了????

    进入正题

    首先不难看出:

     

    因为

    所以原式可以化简为:

    根据手推数据,我们可以发现规律:总有一段连续的i值可以使相等,所以计算这一段和的时候 可以用等差数列公式。

    因此,我们用l和r记录每次相等的左右端点,不考虑边界的情况,r=k/(k/l) 【“除得越少,剩得越多”——仔细领悟】

    最后就是要注意一下边界,r=min(k/(k/l),n);

    然后我们就可以开始写代码了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #define ll long long
     5 using namespace std;
     6 int main() 
     7 {
     8     ll n,k;
     9     scanf("%lld%lld",&n,&k);
    10     ll ans=n*k;
    11     for(ll l=1,r;l<=n;l=r+1) 
    12     {
    13         //cout<<l<<" ";
    14         if(k/l!=0) 
    15         {
    16             r=min(k/(k/l),n);
    17             //cout<<k/(k/l)<<" "<<n<<endl;
    18         }
    19         else r=n; 
    20         ans-=(k/l)*(r-l+1)*(l+r)/2;
    21     }
    22     printf("%lld",ans);
    23     return 0;
    24 }
    233333
  • 相关阅读:
    TCP协议简单套接字通信 客户端
    TCP协议简单套接字通信 服务端
    java课程作业--动手动脑
    Java方法课程作业1,2,3
    java猜数字(实验任务五)
    课程作业02(关于Java的几点讨论)
    java多个int型数据累加求和
    java基本登录界面
    大道至简第一章观后感——java伪代码
    《大道至简—软件编程者的思想》观后感
  • 原文地址:https://www.cnblogs.com/kylara/p/9609564.html
Copyright © 2020-2023  润新知