zoukankan      html  css  js  c++  java
  • BZOJ-1257-[CQOI2007]余数之和sum

    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

     
     

    题解

    这道题看了我挺久的

    我们可以把k%x转化成k-[k/x]*x

    不考虑上限为n的情况  我们假设[k/x]=a(a>0),那么x的区间的head就是[k/(a+1)]+1,tail就是[k/a]

    这样我们可以通过求取这一段区间的值(就是等差数列),求出这段区间的k%x的值

    a每次改成[k/(head-1)]

    head和tail随之改变

    这样依次做下去直到head变为1

    这样时间复杂度就是a的个数  O(√k)

    但是如果x>k呢  实际上x>k的情况只可能在n>k的时候出现

    a开始的值为[k/n]=0,head和tail刚开始的值分别[k/(0+1)]+1和n,发现是正确的

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 ll n,k,ans,sum,h,t,num,cnt;
     5 int main(){
     6     scanf("%lld%lld",&n,&k);
     7     cnt=k/n;
     8     t=n;
     9     h=k/(cnt+1)+1;
    10     ans+=k*(t-h+1)-cnt*(t-h+1)*(t+h)/2;
    11     while (h>1){
    12         cnt=k/(h-1);
    13         t=k/cnt;
    14         h=k/(cnt+1)+1;
    15         ans+=k*(t-h+1)-cnt*(t-h+1)*(t+h)/2;
    16     }
    17     printf("%lld
    ",ans);
    18     return 0;
    19 } 
    View Code
  • 相关阅读:
    [LUOGU] P2196 挖地雷
    [LUOGU] P1020 导弹拦截
    [LUOGU] P2543 [AHOI2004]奇怪的字符串
    [LUOGU] P2759 奇怪的函数
    [LUOGU] P1048 采药
    [LUOGU] P1396 营救
    [LUOGU] P1196 [NOI2002]银河英雄传说
    [LUOGU] 2820 局域网
    知识点
    swich使用
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7617415.html
Copyright © 2011-2022 走看看