http://www.lightoj.com/volume_showproblem.php?problem=1278
题意:问一个数n能表示成几种连续整数相加的形式 如6=1+2+3,1种。
思路:先列式子(N=a+(a+1)+(a+2)+ ...+(a+k-1)=frac{k·(2a+k-1)}{2} ) 继续化成(2a-1=frac{2N}{k} - k ) 可由左式得知,2a-1必为奇数,那么右式必定是一奇一偶,且都为2N的因子。所以只要分解因子记录个数,最后组合求一下即可。
/** @Date : 2016-11-24-22.15 * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : */ #include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> #include <utility> #include <vector> #include <map> #include <set> #include <string> #include <stack> #include <queue> //#include<bits/stdc++.h> #define LL long long #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e6+20; int pri[670000]; int c = 0; bool vis[N*10]; void prime() { MMF(vis); for(int i = 2; i < N*10; i++) { if(!vis[i]) pri[c++] = i; for(int j = 0; j < c && i * pri[j] < N*10; j++) { vis[i*pri[j]] = 1; if(i % pri[j] == 0) break; } } } int main() { int T; int cnt = 0; cin >> T; prime(); while(T--) { LL n; scanf("%lld", &n); LL ans = 1; //while(n % 2 == 0) // n/=2; for(int i = 0; i < c && pri[i]*pri[i] <= n; i++)//记录素因子为奇数的(除2外的) { LL ct = 0; while(n % pri[i] == 0) { if(i != 0) ct++; n /= pri[i]; } ans *= (ct + 1); } if(n > 1 && n != 2) { ans *= 2; } printf("Case %d: %lld ", ++cnt, ans-1); } return 0; }