hdu4473
這題的結果[f(1)+f(2)+...+f(n)]其實就等價于x*y*z<=n的解的個數,然后的方法幾乎就是暴力枚舉了。現場比賽的時候沒想到這一點,太杯具了,浪費了兩個小時的思考時間。其實我們的做法應該是可行的,因為f(n)具有積性性質,也就是若gcd(n, m)=1,則f(n*m)=f(n)*f(m)。而當p為質數時,f(p^k)=(k+1)*(k+2)/2,這樣就能把f(n)數列的前n項和化成一堆多項式的加和。然后用合并同類項的思想,用容斥原理搞,可是代碼量太大了,沒打出來。。。
今天賽題被掛到HDOJ上以后用上面說的枚舉方法打了一下,交上去居然WA,調了半天也沒發現錯誤,最后才懷疑是sqrt和pow函數的精度問題,馬上查了一下解題報告,果然都是手動寫的開平方和開立方函數。加上以后就過了~~
/** hdu4473/win.cpp* Created on: 2012-11-17* Author : ben*/ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <queue> #include <set> #include <map> #include <stack> #include <string> #include <vector> #include <deque> #include <list> #include <functional> #include <numeric> #include <cctype> using namespace std; typedef long long LL;inline LL sqrt2(LL n) {LL m = (LL)sqrt(n + 0.0);while(m * m <= n)m++;while(m * m > n)m--;return m; }inline LL sqrt3(LL n) {LL m = (LL) pow(n, 1 / 3.0);while (m * m * m <= n)m++;while (m * m * m > n)m--;return m; }LL work(LL n) {LL ret = 0;LL t1 = sqrt3(n);ret += t1;for(LL a = 1; a <= t1; a++) {ret += 3 * (n / (a * a) - a);ret += 3 * (sqrt2(n / a) - a);LL t2 = sqrt2(n / a);for(LL b = a + 1; b <= t2; b++) {ret += 6 * (n / (a * b) - b);}}return ret; }int main() { #ifndef ONLINE_JUDGEfreopen("data.in", "r", stdin); #endifint t = 1;LL n;while(scanf("%I64d", &n) == 1) {printf("Case %d: %I64d\n", t++, work(n));}return 0; }轉載于:https://www.cnblogs.com/moonbay/archive/2012/11/12/2766607.html
總結
- 上一篇: {php mysql}
- 下一篇: 使用badboy录制脚本 结合Jmete