C - Sigma Function(LightOJ 1336)

传送门
Password: nefu
C - Sigma Function(LightOJ 1336)_第1张图片

题目大意:
就是给你一个数 n 让你求<=n的所有 i 的因子的个数加起来是偶数的个数
比如 一个数 6: 6的因子有 1 2 3 6,所以1+2+3+6 = 12是偶数所以
符合条件

解题思路:
其实我刚开始的时候也没有什么思路,就想着将 <= n的数都进行素因子
分解,n = p1^e1 * p2^e2 * … * pk^ek
F(n) = (p1^(e1+1)-1)/(p1-1) * ^ (p2^(e2+1)-1)/(p2-1) (pk^(ek+1)-1)/(pk-1)
首先保证其中一项有一个偶数,那考虑起来比较麻烦 所以 我们只需要考虑
奇数的情况就行啦,所以假设 这个 n 是一个平方数,那n == P*P,
F(n) == ((P^3)-1)/(p-1) == P^2+P+1,假设 P是奇数 F(n)是奇数
假设P是偶数 F(n)还是奇数 所以,当这个数是平方数的时候是不符合条件
的,同理当时平方数的2倍的时候,也是不行的,因为当n == 2的时候是
奇数 其实这些规律是在先打完表之后才看出来的看出来了 然后再推一遍
其实推完之后代码就几行。。。
上代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;

#define MM(a) memset(a,0,sizeof(a))

typedef long long LL;
typedef unsigned long long ULL;
const int MAXN = 1e6+5;
const int mod = 1000000007;
const double eps = 1e-7;
/** bool prime[MAXN]; LL p[MAXN]; LL k; void isprime() { k = 0; prime[1] = false; memset(prime, true, sizeof(prime)); for(LL i=2; i<MAXN; i++) { if(prime[i]) { p[k++] = i; for(LL j=i*i; j<MAXN; j+=i) prime[j] = false; } } } LL fac[MAXN/10],num[MAXN/10],cnt; void Dec_prime(int m) { cnt = 0; MM(num); for(LL i=0; p[i]*p[i]<=m&&i<k; i++) { if(m%p[i] == 0) { fac[cnt] = p[i]; while(m%p[i]==0) { num[cnt]++; m /= p[i]; } cnt++; } } if(m > 1) { fac[cnt] = m; num[cnt++] = 1; } } LL Cal(LL a, LL b) { LL ans = 1; while(b--) ans *= a; return ans; } LL ret[MAXN/10]; void Init() { for(int i=0; i<MAXN/10; i++) ret[i] = 1; } **/
int main()
{
    ///isprime();
    int T;
    LL n;
    cin>>T;
    for(int cas=1; cas<=T; cas++)
    {
        cin>>n;
        /** Init(); for(int j=1; j<=100; j++) { Dec_prime(j); for(int i=0; i<cnt; i++) { ret[j] *= (Cal(fac[i],num[i]+1)-1)/(fac[i]-1); } } LL sum = 0; for(int i=1; i<=100; i++) if(ret[i] % 2 == 0) puts("YES"); else puts("NO"); **/
        LL ret = 0;
        for(int i=1; (LL)i*i<=n; i++)///去掉 n^2 和 2*n^2
        {
            ret++;
            if(2*(LL)i*i <= n)
                ret++;
        }
        printf("Case %d: %lld\n",cas,n - ret);
    }
    return 0;
}

去掉注释的那几行 只需要看主程序的就行,注释的是辅助理解的,是为了打表做准备的

你可能感兴趣的:(数学,找规律)