LightOJ 1336. Sigma Function

链接

http://lightoj.com/volume_showproblem.php?problem=1336

题意

t ( t ≤ 100 ) t(t\le100) t(t100) 次询问,每次询问 1 ∼ n ( 1 ≤ n ≤ 1 e 12 ) 1\sim n(1\le n\le 1e12) 1n(1n1e12) 中有多少数的正约数和是偶数。

思路

若正整数 N N N 被唯一分解为 N = p 1 c 1 p 2 c 2 ⋯ p m c m N=p_1^{c_1}p_2^{c_2}\cdots p_m^{c_m} N=p1c1p2c2pmcm,其中 c i c_i ci 都是正整数, p i p_i pi 都是质数。

那么 N N N 的正约数和公式为: ( 1 + p 1 + p 1 2 + ⋯ + p 1 c 1 ) ∗ ⋯ ∗ ( 1 + p m + p m 2 + ⋯ + p m c m ) = ∏ i = 1 m ∑ j = 0 c i p i j (1+p_1+p_1^2+\cdots+p_1^{c_1})*\cdots*(1+p_m+p_m^2+\cdots+p_m^{c_m})=\prod\limits_{i=1}^{m}\sum\limits_{j=0}^{c_i}p_i^j (1+p1+p12++p1c1)(1+pm+pm2++pmcm)=i=1mj=0cipij

因为偶数 ∗ * 奇数 = = = 偶数,所以当公式中每一项都为奇数时,正约数和才为奇数。

易得:

  • p = 2 p=2 p=2 时, ∑ i = 0 c p i \sum\limits_{i=0}^{c}p^i i=0cpi 为奇数。
  • p ≠ 2 p\ne2 p=2 时, c c c 为偶数时, ∑ i = 0 c p i \sum\limits_{i=0}^{c}p^i i=0cpi 为奇数。

所以如果 N N N 的正约数和为奇数,那么公式中除 p = 2 p=2 p=2 外的每一项 c c c 都为偶数。

N N N 是完全平方数或 N / 2 N/2 N/2 是完全平方数。

对于 1 ∼ n 1\sim n 1n 中 有多少正约数和是偶数:

  • i ∗ i ≤ n i*i\le n iin i ∗ i i*i ii 的正约数和为奇数,共有 ⌊ n ⌋ \lfloor\sqrt{n}\rfloor n 个。
  • 2 ∗ i ∗ i ≤ n 2*i*i\le n 2iin 2 ∗ i ∗ i 2*i*i 2ii 的正约数和为奇数,共有 ⌊ ⌊ n 2 ⌋ ⌋ \lfloor\sqrt{\lfloor\frac{n}{2}\rfloor}\rfloor 2n 个。

所以 1 ∼ n 1\sim n 1n 中正约数和是偶数的个数为 n − ⌊ n ⌋ − ⌊ ⌊ n 2 ⌋ ⌋ n-\lfloor\sqrt{n}\rfloor-\lfloor\sqrt{\lfloor\frac{n}{2}\rfloor}\rfloor nn 2n 个。

代码

#include <bits/stdc++.h>
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(),(x).end()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define FI first
#define SE second
using namespace std;
typedef double DB;
typedef long long LL;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;
//head
int main() {
    //freopen("E:/OneDrive/IO/in.txt","r",stdin);
    int tt;
    scanf("%d",&tt);
    for(int cs=1;cs<=tt;cs++) {
        LL n;
        scanf("%lld",&n);
        printf("Case %d: %lld\n",cs,n-(LL)sqrt(n)-(LL)sqrt(n/2));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值