LightOJ - 1278 Sum of Consecutive Integers

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可以表示为几个连续的数之和,最少两个数,问有多少种

比如: 15=1+2+3+4+5=4+5+6=7+8,所以有三种

解题思路:设n=a1+a2+a3+……+am,即n可以表示为m个连续的数之和,因为等差数列公差为1,所以am=a1+m-1;

所以n=m*(a1+a1+m-1)/2,即2a-1=2n/m-m------->a1=n/m-(m-1)/2,因为a1和m,n都是整数,所以n%m=0,(m-1)%2=0;

所以m为n的因子,并且是奇数,所以n的一个奇因子对应一种方案,即只需求n的奇因子个数即可,可以使用算术基本定理将n分解成有限的素数的乘积,求一个数的因子个数是所有素数因子的幂+1,相乘起来就是,那么素数只有2是偶数,

所以奇数因子的个数就是所有 素数因子(除2之外)+1的乘积,,m至少为2,即m一定要大于1,所以要减去1,除去因子1的情况

算术基本定理参考博客:https://blog.csdn.net/qq_40707370/article/details/82534085​​​​​​​

AC代码:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=1e7+10;
bool vis[maxn];
int prime[maxn/10],top;
void get_prime()//素数打表 
{
	top=0;
	memset(vis,0,sizeof(vis));
	for(int i=2;i<maxn;i++)
	{
		if(!vis[i])
		{
			prime[top++]=i;
			for(int j=i+i;j<maxn;j+=i)
				vis[j]=1;
		}
	}
 } 
int main()
{
	get_prime();
	int t;
	long long n;
	cin>>t;
	for(int kase=1;kase<=t;kase++)
	{
		int ans=1;
		cin>>n;
		while(n%2==0)//素因子2不计数 
			n/=2;
		for(int i=1;i<top&&prime[i]*prime[i]<=n;i++)
		{
			int cnt=0;
			if(n%prime[i]==0)
			while(n%prime[i]==0)
			{
				cnt++;
				n/=prime[i];
			}
			ans*=(cnt+1);
		}
		if(n!=1)//因子可能大于根号n,这一步加上,幂为1,所以乘2 
			ans*=2;
		printf("Case %d: %d\n",kase,ans-1);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40707370/article/details/82557629