LIGHT OJ 1278 Sum of Consecutive Integers [因子个数]【数论】

题目链接:http://vjudge.net/contest/137260#problem/W
———————————–.
Sum of Consecutive Integers
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu

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)
=(a+a+k-1)*k/2 =(2*a+k-1)*k/2

然后把式子转换一下
得到这样的结果
2*N/K-K=2*a-1

我们能够知道2*a-1是奇数 所以2*N/K与K之间一定是一个奇数一个偶数的
那么这时候只要求有多少种K的值能够满足 这个式子 就可以了
1)K为奇数 2*N/K为偶数
2)K为偶数 2*N/K为奇数
这时候2*N/K和/K都是2*N的奇因子 其中上述两种情况在计算中不会出现重叠的时候 所以计算两者加和就行了也就是N*2的奇因子,

综上所述 :N的奇数因子的个数即为解。

然后只要求N得奇质因子的个数就行了
根据算数基本定理讲N展开
N=p1^a1*p2^a2*p2^a2*…*pn^an

然后根据因子个数的公式 ∏ i_n (ai+1)
由于我们求的是奇质因子的个数 所有质因子为偶数的时候就不用计算了 当然质因子中只有2一个是偶数

附本题代码
————————.

//#include <bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <cmath>
using namespace std;

#define INF 0x3f3f3f3f
#define pb push_back
#define abs(a) (a)>0?(a):-(a)
#define min(a,b) (a)>(b)?(a):(b)
#define lalal puts("*******")
typedef long long int LL ;
typedef unsigned long long int LLu ;
/*******************************/

const int MOD = 10086;
const int N = 1e7+5;

int prime[700000],kp;
bool Is_or[N];

void shacker()
{
    for(int i=0;i<N;i++) Is_or[i]=1;
    for(int i=2;i<N;i++)
    {
        if(Is_or[i]) prime[kp++]=i;
        for(int j=0;j<kp&&i*prime[j]<N;j++)
        {
            Is_or[i*prime[j]]=0;
            if(0==i%prime[j]) break;
        }
    }
    //printf("%d\n",kp);
    return ;
}

LL solve(LL a)
{
    LL num;
    LL result=1;
    while(a%2==0) a/=2;
    for(int i=1;i<kp&&a>=prime[i];i++)
    {
        num=0;
        while(a%prime[i]==0) a/=prime[i],num++;
        //printf("%I64d-%I64d(%d)  ",a,num,prime[i]);
        result*=(num+1);
    }
    //puts("");
    if(a>1) result*=2;
    return result-1;
}

int main()
{
    shacker();
    int _;
    while(~scanf("%d",&_))
    {
        int kase = 0;
        while(_--)
        {
            LL n;
            scanf("%lld",&n);
            printf("Case %d: %lld\n",++kase,solve(n));
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值