标签: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