zoukankan      html  css  js  c++  java
  • 题解 P2261【[CQOI2007]余数求和】

    P2261【[CQOI2007]余数求和】
    蒟蒻终于不看题解写出了一个很水的蓝题,然而题解不能交了
    虽然还看了一下自己之前的博客
    题目要求:

    [sum_{i=1}^{n}{k mod i} ]

    做些变化

    [sum_{i=1}^{min(n,k)}{k-lfloor frac{k}{i} floor} imes i ]

    [n imes k-sum_{i=1}^{min(n,k)}{lfloor frac{k}{i} floor imes i} ]

    (k<n)分析,直接从1枚举到k肯定不行,但可以发现(lfloor dfrac{k}{i} floor)的值只有(O(sqrt{k}))

    • 对于前(sqrt{k})个数,结果肯定最多有(sqrt{k})
    • 对于剩下的数,(num>sqrt{k} Rightarrow lfloor dfrac{k}{num} floor<sqrt{k}),所以也最多只有(sqrt{k})

    所以可以按值来算,这个东西好像叫除法分块
    如果当前(lfloor dfrac{k}{i} floor)的值为(num),则下一个可以产生新的值的(i'=lfloor dfrac{k}{num} floor)+1
    然后直接把这(num)提出来,用(num)乘上(i)(i'-1)的和就行是这一段(lfloor dfrac{k}{i} floor imes i)的结果了乘法分配律
    然后注意一下是否(i'-1>n)我就因为这个WA了一次。。

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<iomanip>
    #include<cstring>
    #define reg register
    #define EN std::puts("")
    #define LL long long
    inline int read(){
    	int x=0,y=1;
    	char c=std::getchar();
    	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
    	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
    	return y?x:-x;
    }
    LL n,k;
    int main(){
    	n=read();k=read();
    	reg LL ans=0,nex,num;
    	LL haha=n*k;
    	n=std::min(n,k);
    	for(reg int i=1;i<=n;i++){
    		num=k/i;
    		nex=k/num;//nex就是上文的i'-1
    		if(nex>n) nex=n;
    		ans+=num*((i+nex)*(nex-i+1)/2);
    		i=nex;
    	}
    	std::printf("%lld",haha-ans);
    	return 0;
    }
    
  • 相关阅读:
    js_未结束的字符串常量
    [转]关于项目管理的思考
    Nhibernate理解
    Visual Studio 2005常用插件搜罗
    基本概念
    resharper 2.0
    Nhibernate资源
    [转]关于项目管理的知识点
    style
    带分数 蓝桥杯
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/12527318.html
Copyright © 2011-2022 走看看