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

    给出正整数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。
    1<=n ,k<=10^9
    Output

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

    Sample Input

    5 3
    Sample Output

    7

    k%i=k-trunc(k/i)*i,当n>k时,直接把长度为(n-k)的区间长度乘以k加入答案,然后就处理i≤k的时候就可以了,然后就用j=n/(n/i)直接跳到(k/i都相等)区间末尾,然后需要对这个区间的等差数列求和加入答案,输出即可。。 
    注意点:输出%lld,加入答案的时候强制类型转换为long long。。 
    精髓点:
    1:j=n/(n/i) 2:已知区间始末和trunc(k/i)时,求k%i的等差数列的和的公式: ∑=(j-i+1)k-(j-i+1)(i+j)/2*(k/i); #include<cstdio> #include<iostream> using namespace std; int n,k,i,j; long long ans=0; int main() { scanf("%d %d",&n,&k); if (n>k) { ans+=(long long)(n-k)*k; n=k; } j=0; for (i=1;i<=n;i=j+1) { j=k/(k/i); if (j>=n) j=n; cout<<"j is "<<j<<"i is "<<i; system("pause"); ans+=(long long)(j-i+1)*k-(long long)(j-i+1)*(i+j)/2*(k/i); //i代表这一段数的开始位置,j是结束位置.则这一段取mod的结果,利用公式k%i=k-trunc(k/i)*i即等于这一段数字的个数*k,再减去这一段用k/i的结果(i是首项,j是尾项,j-i+1是项数,利用等差数列进行求和) } printf("%lld",ans); return 0; } 12 9 j is 1 i is 1请按任意键继续. . .9/1=9..这一段只有一个数 j is 2 i is 2请按任意键继续. . .9/2=4..这一段也只有一个数 j is 3 i is 3请按任意键继续. . .9/3=3..这一段也只有一个数 j is 4 i is 4请按任意键继续. . .9/4=2..这一段也只有一个数 j is 9 i is 5请按任意键继续. . .9/5=1,包括其后的9/6=1,9/7=1,9/8=1,9/9=1.这一段有5个数 39

      

  • 相关阅读:
    bzoj 1013: [JSOI2008]球形空间产生器sphere
    bzoj 1012: [JSOI2008]最大数maxnumber
    bzoj 1010: [HNOI2008]玩具装箱toy
    bzoj 1008: [HNOI2008]越狱
    bzoj 1007: [HNOI2008]水平可见直线
    UVa12105 越大越好
    POJ
    最优点配对问题(紫书)
    Ned 的难题
    UVA
  • 原文地址:https://www.cnblogs.com/cutemush/p/12801329.html
Copyright © 2011-2022 走看看