LightOJ1278 Sum of Consecutive Integers 素数筛法+数学分析

来源:互联网 发布:mac fifa 编辑:程序博客网 时间:2024/06/05 16:18

Description
Given an integer N, you have to find the number of ways you can express N as sum of consecutive integers. You have to use at least two integers.
For example, N = 15 has three solutions, (1+2+3+4+5), (4+5+6), (7+8).
Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case starts with a line containing an integer N (1 ≤ N ≤ 1014).
Output
For each case, print the case number and the number of ways to express N as sum of consecutive integers.
Sample Input
5
10
15
12
36
828495
Sample Output
Case 1: 1
Case 2: 3
Case 3: 1
Case 4: 2
Case 5: 47

题意是给出一个数n,求出有多少种连续整数和等于n(连续整数至少两个)。

我们由 n = a + ( a + 1 ) + ( a + 2 ) + ( a + 3 ) + …… + ( a + k - 1 )  => n = ( 2a + k -1) / 2 * k  =>2n / k - k = 2a - 1  => 2n / k - k 是一个奇数。

如果k是一个偶数,那么2n/k必是奇数,偶数/偶数=奇数;

如果k是一个奇数,那么2n/k必是偶数,偶数/奇数=偶数。

最后可以得到,对于n = 2^a1 * 3^a2 * 5^a3 * 7^a4 * --- * pri^an,计算结果就是 (a2+1) * (a3+1) * (a4+1) * -- * (an+1) - 1。


#include <iostream>#include <cstdio>#include <map>#include <set>#include <vector>#include <queue>#include <stack>#include <cmath>#include <algorithm>#include <cstring>#include <string>using namespace std;#define INF 0x3f3f3f3ftypedef long long LL;#define maxn 10000005int prime[700000],c;bool v[maxn];void p(){    LL i,j,n=maxn,m;    c=0;    m=(LL)sqrt(n+0.5);    memset(v,false,sizeof(v));    for(i=2;i<=m;i++)        if(!v[i]){            for(j=i*i;j<=n;j+=i)                v[j]=1;        }    for(j=2;j<=n;j++){        if(!v[j]){            prime[c++]=j;        }    }}int main(){    int t;    LL l;    p();    scanf("%d",&t);    for(int i=1;i<=t;i++){        cin>>l;        while(l%2==0){            l/=2;        }        LL cc=1;        for(int j=1;j<c;j++){            if(l==1){                break;            }            if(l%prime[j]==0){                int s=0;                while(l%prime[j]==0){                    l/=prime[j];                    s++;                }                cc*=s+1;            }        }        if(l>1){            cc*=2;        }        printf("Case %d: %lld\n",i,cc-1);    }    return 0;}


0 0
原创粉丝点击