您的位置:首页 > 其它

Sum of Consecutive Integers

2017-05-18 21:36 369 查看

Sum of Consecutive Integers

题目链接

题意

问N能够分解成多少种不同的连续数的和.

思路

连续数是一个等差数列:\[
\frac{(2*a1 + n -1)*n}{2} = T\]

那么\(\frac{2*T}{n}-n = 2*a1-1\),所以当\(n\)为\(T\)的奇因子的时候符合要求.

那么当\(n\)为偶数的时候\(\frac{2*T}{n}-(n-1) = 2*a1\);因为\((n-1)\)为奇数,\(2*a1\)为偶数,所以\(\frac{2T}{n}\)为奇数,所以另\(t\)上下含有的2的个数,必定上下含有2的个数必定相等,\(t = 2^t\)那么就得到\(\frac{\frac{2T}{t}}{\frac{n}{t}}\),那么另\(u = \frac{n}{t}\)那么\(u\)就是\(T\)的奇数因子,那么\(n = u*t\)就行了,因为每个\(n\)的值会一一对应一个连续的序列,所以即使当\(n\)为偶数的时候是通过求\(T\)的奇数因子而求得.所以通过求\(n\)为奇数时和\(n\)为偶数时,都是求T的奇数因子而求得,那么所有的种数就是求\(T\)的奇数因子的个数,除去1的时候。

然后就素数打表,\(T = p1^{k1} * p2^{k2}*p3^{k3}*...pn^{kn}\),那么如果\(T\)为偶数的话就把\(p\)为2的去掉,那么奇数因子个数就为\((k1+1)*(k2+1)*...(kn+1)\),最后再减个1就行了.

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
bool prime[10000005];
int table_prime[1000005];
int main(void)
{
for(int i = 2; i < 10000; i++)
{
if(!prime[i])
for(int j = i; (i*j) <= 10000000; j++)
prime[i*j] = true;
}
int cn = 0;
for(int i = 2; i <= 10000000; i++)
if(!prime[i])
table_prime[cn++] = i;
int T;
scanf("%d",&T);
int __cn = 0;
while(T--)
{
LL n;
scanf("%lld",&n);
int f = 1;
LL u = 0,sum = 1;
while(n%2 == 0)
n/=2;
while(n > 1&&f < cn)
{
if((LL)table_prime[f]*(LL)table_prime[f] > n)
break;
while(n%table_prime[f] == 0)
{
u++;
n/=table_prime[f];
}
sum = sum * (u+1);
u = 0;
f++;
}
if(n > 1)
sum *= (LL)2;
sum--;
printf("Case %d: ",++__cn);
printf("%lld\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: