BZOJ 1257: [CQOI2007]余数之和sum【神奇的做法,思维题】
2017-07-03 23:29
453 查看
1257: [CQOI2007]余数之和sum
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4474 Solved: 2083
[Submit][Status][Discuss]
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 3Sample Output
7HINT
50%的数据满足:1<=n, k<=1000 100%的数据满足:1<=n ,k<=10^9Source
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1257分析:用了一个看起来比较奇怪的方法,首先x % i = x – (int)(x / i) * i,这个很好YY吧
然后可以找出每个(int)(x / i)相等的一段用等差数列求和来做。可以证明最多分成sqrt(n)段。
下面给出AC代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } int n,k; ll ans; int main() { n=read(); k=read(); if(n>k) { ans=(ll)(n-k)*k; n=k; } int r; for(int i=1;i<=n;i=r+1) { int t=k/i; r=k/t; if(r>=n)r=n; ans+=(ll)(r-i+1)*k-(ll)(r-i+1)*(i+r)/2*t; } printf("%lld\n",ans); return 0; }
相关文章推荐
- [BZOJ]1257 [CQOI2007] 余数之和sum 分块优化
- bzoj 1257: [CQOI2007]余数之和sum
- BZOJ1257 [CQOI2007]余数之和sum
- BZOJ1257 [CQOI2007]余数之和sum(枚举商)
- 【BZOJ1257】[CQOI2007]余数之和sum【余数求和】【分块】
- BZOJ 1257: [CQOI2007]余数之和sum
- bzoj 1257 [CQOI2007]余数之和sum 数学,分段优化
- bzoj1257 [CQOI2007]余数之和sum
- BZOJ1257: [CQOI2007]余数之和sum
- BZOJ 1257[CQOI2007]余数之和sum | 数论
- BZOJ 1257 [CQOI2007]余数之和sum 数论
- [BZOJ1257][CQOI2007]余数之和sum
- [bzoj1257][CQOI2007]余数之和sum
- 【BZOJ】1257 [CQOI2007]余数之和sum 公式变形
- bzoj1257 [CQOI2007]余数之和sum(关于反演sqrt(n)复杂度的简单解释)
- bzoj千题计划173:bzoj1257: [CQOI2007]余数之和sum
- bzoj 1257: [CQOI2007]余数之和sum
- _bzoj1257 [CQOI2007]余数之和sum【小技巧】
- bzoj 1257: [CQOI2007]余数之和sum
- 【bzoj1257】[CQOI2007]余数之和sum