Sum of Consecutive Integers

Sum of Consecutive Integers

题目链接

题意

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

思路

连续数是一个等差数列:$$
\frac{(2a1 + 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;
}
posted @ 2017-05-18 21:36  sCjTyC  阅读(410)  评论(0编辑  收藏  举报