• P2261 [CQOI2007]余数求和


    题目

    题目给定柿子\(\displaystyle G(n,k)=\sum_{i=1}^{n}k\ mod\ i\)

    我们知道\(mod\)是取模运算,即\(n\)整取\(k\)后的余数

    ∴我们设可以知道\(k\ mod\ i =k-i*\lfloor{\frac {k}{i}}\rfloor\)

    ∴我们的柿子就阔以变成这个亚子\(\displaystyle G(n,k)=\sum_{i=1}^{n}{k-i*\lfloor{\frac{k}{i}}\rfloor}\)

    我们可以在把柿子简化一下

    使这个柿子变成了\(\displaystyle n*k-\sum_{i=1}^{n}{i*\lfloor{\frac{k}{i}}\rfloor}\)

    我们就不难发现我们只需要考虑降低一下后面这个\(\sum\)的复杂度了

    我们考虑一个数\(k\)

    我们发现当\(i>k\)的时候,那么\(\lfloor{\frac{k}{i}}\rfloor\)一定是等于\(0\)
    (因为分母比分子大了),所以我们在程序中判断一下\(k\)\(i\)的大小关系就阔以了

    然后我们考虑一下当\(i\leq k\)的时候呢,这个时候我们就要考虑一下\(\lfloor \frac{k}{i}\rfloor\)的数值的关系了

    我们考虑一个数\(i\),且存在\(j=\lfloor \frac{k}{\lfloor \frac{k}{i}\rfloor}\rfloor\),我们就会发现\(\lfloor\frac{k}{j}\rfloor\)=\(\lfloor \frac{k}{i}\rfloor\),是不是很神奇?(读者可自行举栗子来验证一下)

    我们会惊奇地发现:当\(i\)\(i\)\(\lfloor\frac{k}{\lfloor \frac{k}{i}\rfloor}\rfloor\)(即\(j\))的区间里所有\(\lfloor \frac{k}{i} \rfloor\)都会是同一个值

    这其实是数论分块的一部分,这其实是个除法分块

    然后放代码(较丑勿喷)

    #include<bits/stdc++.h>
    using namespace std;
    long long ans, n, k;
    int main(){
    	scanf("%lld%lld", &n, &k);
    	ans = n * k;
    	for(int i = 1, j = 1; i <= n; i = j + 1){
    		if(i <= k) j = min(n, k/ (k / i));//防止j越界 
    		else break;//i > k时(k/i == 0) 直接退出
    		ans -= (k / i) * (j - i + 1) * (i + j) / 2;
    	}
    	printf("%lld\n", ans);
    	return 0;
    }
    

    完美结束,撒花✿✿ヽ(°▽°)ノ✿

  • 相关阅读:
    条款41:了解隐式接口和编译期多态
    条款41:了解隐式接口和编译期多态
    虚机制
    条款31:将文件间的编译依存关系降至最低
    条款30:透彻了解inlining的里里外外
    条款28:避免返回handles 指向对象内部成分
    条款27:尽量少做转型动作
    条款26:尽可能延后变量定义式的出现时间
    条款25: 考虑写出一个不抛异常的swap函数
    APP测试工程师面试题:之一
  • 原文地址:https://www.cnblogs.com/wsdslll/p/13345465.html
Copyright © 2020-2023  润新知