Problem H
{sum+=i++} to Reach N
Input: standard input
Output: standard output
Memory Limit: 32 MB
All the positive numbers can be expressed as a sum of one, two or more consecutive positive integers. For example 9 can be expressed in three such ways, 2+3+4, 4+5 or 9. Given an integer less than (9*10^14+1) or (9E14 + 1) or (9*1014 +1) you will have to determine in how many ways that number can be expressed as summation of consecutive numbers.
Input
The input file contains less than 1100 lines of input. Each line contains a single integer N (0<=N<= 9E14). Input is terminated by end of file.
Output
For each line of input produce one line of output. This line contains an integer which tells in how many ways N can be expressed as summation of consecutive integers.
Sample Input
9
11
12
Sample Output
3
2
2
假设由n个数组成 a,a+1,a+2...a+n-1
(a+a+n-1)/2 = N;
(2*a+n-1)*n = 2*N
n奇数 则2*a+n-1为偶
n偶数 则2*a+n-1为奇
又因为2*N为偶数,即:偶数 = 奇数*偶数
再由于:
偶数 = 奇数*偶数 或者 偶数*偶数
因此,只要枚举2*N的各个奇数因子出现的次数a1,a2...ak则排列组合出答案=(a1+1)*(a2+1)...*(ak+1)。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
#define ll long long
const int maxn = 30000003;
vector<ll> prime;
ll N;
bool is_p[maxn];
void get_prime(int sn){
for(int i = 0; i <= sn; i++) is_p[i] = true;
for(ll i = 2; i*i <= sn; i++){
if(is_p[i]){
for(ll j = i*i; j <= sn; j+=i) is_p[j] = false;
}
}
for(ll i = 2; i <= sn; i++) if(is_p[i]) prime.push_back(i);
}
void computing(){
ll ans = 1;
for(int i = 0; prime[i]*prime[i] <= N; i++){
ll tem = 0;
while(N%prime[i] == 0){
tem++;
N = N/prime[i];
}
if(tem != 0 && prime[i] > 2){
ans *= (tem+1);
}
}
if(N > 1) ans *= 2;
printf("%lld\n" , ans);
}
int main(){
get_prime(maxn-1);
while(~scanf("%lld" , &N)){
computing();
}
return 0;
}