标签:
---》题意:给一个函数的定义,F(n)代表n的所有约数之和,并且给出了整数拆分公式以及F(n)的计算方法,对于一个给出的N让我们求1 - N之间有多少个数满足F(x)为偶数的情况,输出这个数。
---》分析:来考虑F(x)为奇数的情况,给据题目中给我们的公式,,如果F(x)为奇数,那么这个多项式里面的任何一项都必须是奇数,可以知道p = 2时, p^e - 1肯定是奇数,如果p != 2,当且仅当e为偶数的时候,此项为奇数,证明如下:
原式变形为[ p^(e+1) -p + (p-1) ]/ (p-1) = p*(p^e-1)/(p-1) + 1;
所以p/(p-1) = 1 ,p^e一定是奇数(因为p是质数,质数肯定是奇数),所以p^e-1为偶数,所以下划线式肯定是奇数,证明成立。
那么题目中的公式可以写成下面的形式:
2^k0 * 3^(2*k1) * 5^(2*k2) * ... * pn^(2*kn);下划线式可以表达为num ^ 2;
又k0>=0, 所以满足条件的解为num^2和2 * num^2;因为满足2的更高次幂也一定是2的倍数,不可重复计算。代码如下:
--》注意:这个题目不可以直接循环做,尽管题目中给的时间较长,但直接暴力仍然会超,这里直接计算,sqrt无法强制转换为LL,但是此题L也够了;
--》感悟:数论的题目特点就是代码超短,但思维量和证明超多的那种……
#include<cstring> #include<cstdio> #include<cmath> #include<iostream> using namespace std; #define L long int main() { int t,ca = 0; long long n; scanf("%d",&t); while(t--) { scanf("%lld",&n); L ans = 0; double tmp = n; ans = L(sqrt(tmp)) + L(sqrt(tmp/2)); printf("Case %d: %ld\n",++ca,n-ans); } return 0; }
LightOJ 1336 Sigma Function(数论 整数拆分推论)
标签:
原文地址:http://www.cnblogs.com/jifahu/p/5594346.html