• BZOJ 1257: [CQOI2007]余数之和sum【神奇的做法,思维题】


    1257: [CQOI2007]余数之和sum

    Time Limit: 5 Sec  Memory Limit: 162 MB
    Submit: 4474  Solved: 2083
    [Submit][Status][Discuss]

    Description

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

    Input

    输入仅一行,包含两个整数n, k。

    Output

    输出仅一行,即j(n, k)。

    Sample Input

    5 3

    Sample Output

    7

    HINT

    50%的数据满足:1<=n, k<=1000 100%的数据满足:1<=n ,k<=10^9

    Source

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1257

    分析:用了一个看起来比较奇怪的方法,首先x % i = x – (int)(x / i) * i,这个很好YY吧
    然后可以找出每个(int)(x / i)相等的一段用等差数列求和来做。可以证明最多分成sqrt(n)段。

    下面给出AC代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 inline int read()
     5 {
     6     int x=0,f=1;
     7     char ch=getchar();
     8     while(ch<'0'||ch>'9')
     9     {
    10         if(ch=='-')
    11             f=-1;
    12         ch=getchar();
    13     }
    14     while(ch>='0'&&ch<='9')
    15     {
    16         x=x*10+ch-'0';
    17         ch=getchar();
    18     }
    19     return x*f;
    20 }
    21 int n,k;
    22 ll ans;
    23 int main()
    24 {
    25     n=read();
    26     k=read();
    27     if(n>k)
    28     {
    29         ans=(ll)(n-k)*k;
    30         n=k;
    31     }
    32     int r;
    33     for(int i=1;i<=n;i=r+1)
    34     {
    35         int t=k/i;
    36         r=k/t;
    37         if(r>=n)r=n;
    38         ans+=(ll)(r-i+1)*k-(ll)(r-i+1)*(i+r)/2*t;
    39     }
    40     printf("%lld
    ",ans);
    41     return 0;
    42 }
  • 相关阅读:
    C语言 · 阶乘计算 · 基础练习
    C语言 · 查找整数 · 基础练习
    UML课程复习重点
    运维参考
    mysql语法总结
    Python杂篇
    Python练习题
    Python参考
    k8s中ipvs和iptables选择
    安装cni网络插件-非必须
  • 原文地址:https://www.cnblogs.com/ECJTUACM-873284962/p/7113561.html
Copyright © 2020-2023  润新知