zoukankan      html  css  js  c++  java
  • [Luogu P2261] [CQOI2007]余数求和 (取模计算)

    题面

    传送门:https://www.luogu.org/problemnew/show/P2261


    Solution

    这题显然有一个O(n)的直接计算法,60分到手。

    接下来我们就可以拿出草稿纸推一推式子了

    首先,取模运算在这里很不和谐,我们得转换一下。

    对于任意取模计算,我们都有:

     所以,我们可以做以下推算

    经过一些手算,我们发现k/i(向下取整)是由一段一段的区间组成的,如下图

    显然,每段区间的右端点可以通过二分的方法来找

    对于每一段区间,我们可以把k/i提出来,括号里面就变成了(i+(i+1)+(i+2)+(i+3)+.....+右端点) 直接用等差数列来算就好

    时间复杂度我不会算XD  


    Code

    //Luogu P2261 [CQOI2007]余数求和
    //Jul,7th
    //取模运算推一推
    #include<iostream>
    #include<cstdio>
    using namespace std;
    int main(int argc, char **argv)
    {
        //freopen("sum.in","r",stdin);
        //freopen("sum.out","w",stdout);
        long long n,K;
        scanf("%lld%lld",&n,&K);
        
        long long ans=n*K;
        for(long long i=1;i<=n;i++)
        {
            long long temp=K/i;
            long long l=i,r=n,mid,nxt=i;
            while(l<=r)
            {
                mid=(l+r)/2;
                if(K/mid==temp)
                    nxt=max(nxt,mid),l=mid+1;
                else
                    r=mid-1;
            }
            ans-=(((i+nxt)*(nxt-i+1))/2)*temp;
            i=nxt;
        }
        
        printf("%lld",ans);
        return 0;
    }
    正解(C++)
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    安装触动精灵
    云集微助手安装教程和授权说明old
    造粉神器下载地址
    兵工厂安装和使用教程
    云集微助手-操作简介
    转:二叉树的深度优先遍历和广度优先遍历
    转:背包问题的解法
    Moco搭建测试服务器
    Jmeter的内嵌函数和变量
    Jmeter输出HTML的性能测试报告
  • 原文地址:https://www.cnblogs.com/GoldenPotato/p/9267496.html
Copyright © 2011-2022 走看看