Light oj 1245 多校B
题意是说给你一个数n,求n+n/1+n/2+...n/(n-1)+1, 1<=n<2^31,
比赛的时候我想到的是‘二分的做法’,i=1,每次i++,数的后半段乘上对应的i的值,只要到sqrt(n);1...sqrt(n)直接暴力枚举。
#include<bits/stdc++.h> using namespace std; typedef long long ll; int main() { int t,casee=1; ll n; scanf("%d",&t); while(t--) { scanf("%lld",&n); ll m=n,sum=0;
// '二分计算sum' for(ll i=1; m>sqrt(n); i++) { sum+=(m-n/(i+1))*i; m=n/(i+1); } //printf("%lld\n",sum);
//枚举1...sqrt(n); for(ll i=sqrt(n); i>=1; i--) { sum+=n/i; } printf("Case %d: ",casee++); printf("%lld\n",sum); } return 0; }
但是当时思路不清楚,草草的写好之后验了一组数据错了之后就放弃了,
赛后学长讲题的时候发现和这个思路差不多,不过学长的方式更好。
#include<bits/stdc++.h> using namespace std; typedef long long ll; int main() { int t,casee=1; ll n; scanf("%d",&t); while(t--) { scanf("%lld",&n); ll m=n,sum=0; for(ll i=2; i<=sqrt(n); i++) { sum+=(m-m/i)*(i-1); m=n/i; } for(ll i=m; i>=1; i--) { sum+=n/i; } printf("Case %d: ",casee++); printf("%lld\n",sum); } return 0; }