题目链接:传送门
题意: 将给定的n分成 连续的数的和,至少有两个数,看能有多少种方案。
分析:
a + (a + 1) +
(a + 2) + ... +(a + k - 1) = n;
===> (2*a + k - 1) * k = 2*n;
===> (2*a - 1)*k = 2*n - k*k;
===> 2*a - 1 =
2*n/k - k;
等式的左边为奇数,那么右边也必须为奇数,则k必须为n的奇约数
因此将n素因子分解就可以了
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <set> #include <map> #include <queue> #define PB push_back #define MP make_pair #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,l,h) for(int i=(l);i<=(h);++i) #define DWN(i,h,l) for(int i=(h);i>=(l);--i) #define IFOR(i,h,l,v) for(int i=(h);i<=(l);i+=(v)) #define CLR(vis) memset(vis,0,sizeof(vis)) #define MST(vis,pos) memset(vis,pos,sizeof(vis)) #define MAX3(a,b,c) max(a,max(b,c)) #define MAX4(a,b,c,d) max(max(a,b),max(c,d)) #define MIN3(a,b,c) min(a,min(b,c)) #define MIN4(a,b,c,d) min(min(a,b),min(c,d)) #define PI acos(-1.0) #define INF 1000000000 #define LINF 1000000000000000000LL #define eps 1e-8 #define LL long long using namespace std; const int maxn = 1e7+10; int p[maxn/10],num; bool vis[maxn]; void init(){ num=0; CLR(vis); FOR(i,2,maxn-1){ if(!vis[i]){ p[num++]=i; IFOR(j,i+i,maxn-1,i) vis[j]=1; } } } int main() { init(); int t,cas=1; scanf("%d",&t); while(t--){ LL n; scanf("%lld",&n); LL ans = 1; for(int i=0;i<num&&p[i]<=n;i++){ if(n%p[i]==0){ int cnt = 0; while(n%p[i]==0)n=n/p[i],cnt++; if(p[i]&1) ans=ans*(LL)(cnt+1); } } if(n>1&&n&1) ans=ans*2LL; ans--; printf("Case %d: %lld\n",cas++,ans); } return 0; }
时间: 2024-10-09 03:48:09