题意:
求1-n中约数和为偶数的数的个数
记住一个定理:。。。平方数 及其 平方数的2倍 的约数和为奇数 then。。。。减啦
证明:
。。。。我jiao着人家写的很详细,so 看看人家写的吧!
转载至:https://blog.csdn.net/Rain722/article/details/64439310
数x的因子和 f(x)= (1+p1+p1^2+p1^3+...+p1^a1)*(1+p2+p2^2+...+p2^a2)*...*(1+pn+pn^2+...+pn^an);
因为偶数乘偶数还是偶数,奇数乘奇数还是奇数,奇数乘偶数是偶数,所有必须让每个括号内都是奇数,然后减去约数和为奇数的个数就是答案了。
1.当x有素因子2的时候,2所对应的括号内的和肯定是一个奇数,因为偶数加1一定是奇数。
2.除了2以外,所有的素数都是奇数,要使x得其他素因子对应的括号内的和为奇数,就必须保证x有偶数个该素因子,即ai必须为偶数。
3.满足上面两个条件的数,就是一个平方数,也就是说约数和为奇数的数x,它必定是一个平方数,当然这个数x乘上2也是满足2*x的约数和为奇数的。
所以只要减去用n减去sqrt(n)和sqrt(n/2)就是答案了。也可以找n以内的平方数的个数,以及2*平方数不超过n的数的所有个数和,用n减完之后就是答案。
代码如下:
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cmath> #define MOD 2018 #define LL long long #define ULL unsigned long long #define maxn 100009 #define Pair pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define _ ios_base::sync_with_stdio(0),cin.tie(0) //freopen("1.txt", "r", stdin); using namespace std; const int LL_INF = 0x7fffffffffffffff,INF = 0x3f3f3f3f; int main() { int T; LL n; int kase = 0; cin>> T; while(T--) { cin>> n; LL temp = n; n -= (LL)sqrt(temp); n -= (LL)sqrt(temp/2); printf("Case %d: %lld ", ++kase, n); } return 0; }
第二种方法:
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cmath> #define MOD 2018 #define LL long long #define ULL unsigned long long #define maxn 100009 #define Pair pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define _ ios_base::sync_with_stdio(0),cin.tie(0) //freopen("1.txt", "r", stdin); using namespace std; const int LL_INF = 0x7fffffffffffffff,INF = 0x3f3f3f3f; int main() { int T; LL n; int kase = 0; cin>> T; while(T--) { LL ans = 0; cin>> n; for(LL i=1; i*i<=n; i++) { ans++; if(2*i*i <= n) ans++; } printf("Case %d: %lld ", ++kase, n - ans); } return 0; }