zoukankan      html  css  js  c++  java
  • 【数学】At Coder 091 D题

    【深夜题解】

    题目链接:https://arc091.contest.atcoder.jp/tasks/arc091_b

    题目大意:给出两个正整数N、K,找出所有的不大于N的正整数对(a,b)使b%a>=K,求数对总数。

    解题思路:

    解这道题的历程很纠结……倒不是题目问题而是心理问题,值得反思,应该克服浮躁畏难情绪。

    回归题目,首先对于b%a>=K,我们可以想到a>K这一必须条件,当a==K+1时,b==d*a+K;当a==K+2时,b==d*a+K+1或d*a+K。

    d可以从0开始取值,只要满足b不大于N即可,那么其实每个d的最大值都十分好求,d==(N-K-x)/a;(a>x+K>=K)

    但是如果枚举每个x和a的话时间复杂度是N^2,,会T。于是我们根据此题的特殊条件,寻求只枚举a的解法。

    对于每一个a,b%a的值都有(a-k)种可能,如果每种可能的d都一样,那我们就可以省略枚举d了。

    那么每种可能的d到底一不一样呢?答案是否定的。

    但是,我们可以发现对于确定的a,每种可能的d最多只会相差1。

    我们来仔细分析d的组成:

    (N-K-x)/a==(N/a*a+N%a-K-x)/a==N/a+(N%a-K-x)/a。

    对于每个x,最终种数是d+1(从0开始取值),所以ans+=N/a+(N%a+a-K-x)/a;

    而K+x是小于a的,所以后边那一团恒正,且小于2*a,只需要判断是否大于a(商为1还是0)就行了。

    那么商为1的到底有多少个?N%a+a-K-x>=a=====N%a-K-x>=0=====N%a-K>=x。我们可以o(1)求出能提供格外贡献的x有多少个了,答案就是N%a-K+1(x也从0开始取)。

    所以对于一个a,它提供的贡献是(N/a)*(a-k)+max(0,N%a-K+1)。

    另外此题还有一个trick,要求a,b是正整数,当k==0的时候,b==0在本算法中也是合理解,必须排除,所以特判一下(ans-N)。

    下面放1msAC代码:

    #include<stdio.h>
    
    int _max(int a,int b){return a>b?a:b;}
    
    int main(){
        
        long long ans=0;
        int n,k,i,a;
        scanf("%d%d",&n,&k);
        for(i=k+1;i<=n;i++){
            ans+=(long long)(n/i)*(i-k);
            ans+=(long long)_max(0,n%i-k+1);
        }
        if(k==0)ans-=(long long)n;
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    数据仓库
    数据库事务隔离级别与锁
    并发包之Future:代码级控制超时时间
    axis2 webservice 发布、调用与项目集成
    配置远程控制
    解决局部刷新的问题
    Sharepoint 2013 搜索高级配置(Search Scope)
    重启IIS报错:IIS 服务或万维网发布服务,或者依赖这 服务可能在启动期间发生错误或者已禁用
    错误提示:此产品的试用期已经结束
    Sharepoint 2013 启用搜做服务
  • 原文地址:https://www.cnblogs.com/L-Excalibur/p/8547269.html
Copyright © 2011-2022 走看看