标签:des style blog color os io for ar
3 1 3 100
Case #1: 1 Case #2: 30 Case #3: 15662489HintIn the second test case, there are six levels(1x1,1x2,1x3,2x2,2x3,3x3) Here is the details for this game: 1x1: 1(K=1); 1x2: 2(K=1); 1x3: 3(K=1); 2x2: 2(K=1), 4(K=2); 2x3: 6(K=1); 3x3: 3(K=1), 9(K=3); 1+2+3+2+4+6+3+9=30
题意:给你个n,让你求在n的范围内,能否将一个矩形分成若干个相同大小为k的正方形,对应有val值,让你统计在n内的所有可能的分数总值
思路:首先我们来试着求解∑(n*i)/(gcd(n/k, i/k)) {1<=i <= n} ,那么我们可以确定的是如果可以把n*m的矩形分成大小为k的正方形的话,那么k一定是gcd(n, i)的因子,那么对于一项来说因为公式可以变形为(n*i*k)/gcd(n, i) -> n*(i/c1 + i/c2 + ...) {k枚举所有的可能},
就拿6*1, 6*2, 6*3, 6*4, 6*5, 6*6来说,对应的k依次有
1;1、2; 1、3;1、2;1;1,2,6,那么cj是n的因子,那么i/cj就是因子对应的系数,我们再从所有的i来讲,对于因子cj我们可以计算出所有可能的数,比如因子cj,我们可以得到cj, 2*cj, 3*cj, 4*cj....n,那么对应的系数就是我们需要的i/cj,累加起来计算是:
num[cj] = (1+2+...+n/cj)=(1+n/cj)*(n/cj)/2,然后最后是递推:
ans[n]=ans[n-1]+val[n] {val[n]=∑num[cj] {1<=i <= n}}
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define ll __int64 using namespace std; const int maxn = 500005; const ll mod = 1ll<<32; ll num[maxn], dp[maxn]; void cal() { for (ll i = 1; i < maxn; i++) for (ll j = i; j < maxn; j += i) num[j] += (j/i+1) * (j/i) / 2; } void init() { memset(num, 0, sizeof(num)); cal(); dp[1] = 1; for (ll i = 2; i < maxn; i++) { dp[i] = dp[i-1] + num[i]*i; dp[i] = dp[i] % mod; } } int main() { init(); int t, n, cas = 1; scanf("%d", &t); while (t--) { scanf("%d", &n); printf("Case #%d: %I64d\n", cas++, dp[n]); } return 0; }
HDU - 4944 FSF’s game,布布扣,bubuko.com
标签:des style blog color os io for ar
原文地址:http://blog.csdn.net/u011345136/article/details/38520773