异或约数和 [异或相关]

异 或 约 数 和 异或约数和


最 初 想 法 \color{blue}{最初想法}

[ 1 , x ] [1, x] [1,x] 内含有 x x x 这个约数的数个数为 c n t = ⌊ N x ⌋ cnt = \lfloor \frac{ N } { x } \rfloor cnt=xN,
c n t cnt cnt 为偶数时, 贡献为 0 0 0, 当 c n t cnt cnt 为奇数时, 对整体答案贡献为 异或 x x x,
枚举 x ∈ [ 1 , N ] x∈[1,N] x[1,N] 直接计算贡献, 复杂度 O ( N ) O(N) O(N) .
整除分块 加上类似 这里 的方法可以优化到 O ( N l o g N ) O(\sqrt{N}logN) O(N logN), 但是仍然不能 A C AC AC.


正 解 部 分 \color{red}{正解部分}

有一个规律, 设 g ( x ) g(x) g(x) [ 1 , x ] [1,x] [1,x] 内的异或和, 则

g ( x ) = { 0      奇 数 x     e l s e + { 1      ⌈ N 2 ⌉ 为 奇 数 0      e l s e g(x)= \begin{cases} 0\ \ \ \ 奇数\\ x\ \ \ else \end{cases} +\begin{cases} 1 \ \ \ \ \lceil \frac{N}{2}\rceil为奇数 \\ 0 \ \ \ \ else\end{cases} g(x)={0    x   else+{1    2N0    else

于是前面需要 O ( l o g N ) O(logN) O(logN) 计算的只需要 O ( 1 ) O(1) O(1) 了, 总体复杂度 O ( N ) O(\sqrt{N}) O(N ) , 可以 A C AC AC .


实 现 部 分 \color{red}{实现部分}

没什么好说的 …

#include<bits/stdc++.h>
#define reg register
typedef long long ll;

ll N;
ll Ans;

ll Sum(ll x){
        if(!x) return 0;
        ll s_1, s_2;
        if(x & 1) s_1 = 0;
        else s_1 = x;
        ll tmp = (N-1)/x + 1;
        if(tmp & 1) s_2 = 1;
        else s_2 = 0;
        return s_1 + s_2;
}

int main(){
	scanf("%lld", &N);
	for(reg ll l = 1, r; l <= N; l = r+1){
		r = N/(N/l);
		if((N/l & 1) == 0) continue ;
		Ans ^= Sum(r) ^ Sum(l-1);
	}
        printf("%lld\n", Ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值