![[51nod异或约数和] 整除分块+打表找规律 [51nod异或约数和] 整除分块+打表找规律](/default/index/img?u=L2RlZmF1bHQvaW5kZXgvaW1nP3U9YUhSMGNITTZMeTl3YVdGdWMyaGxiaTVqYjIwdmFXMWhaMlZ6THpFek1TODBaakJoTjJSa05tRm1NVGhtTnpkaVlqbGpaREV6TTJObE9UUmpNR1l3WWk1d2JtYz0=)
- emm。首先我想到一个n∗log2n的算法,就是对于每一个数,枚举它的倍数,然后筛一下。35分get。
- 诶,在计算总答案的公式中,一个数被异或的时候,肯定是被作为约数的时候。那么一个数被异或的次数肯定是in。如果为奇数,就把它异或上,不然就不管。O(n)算法,45分美滋滋。
- 嗯?in?整除分块搞一下是不是就n了啊。哦,但是它好像涉及到一个求连续区间的异或和问题,我们需要O(1)。转化一下,l到r的区间异或和等于1到l−1的异或和^1到r的异或和。从1到n的异或和怎么O(1)求?打表找规律!
- 设f(n)为1到n的异或和,则:
if(n mod 4=1), f(n)=1
if(n mod 4=2), f(n)=n+1
if(n mod 4=3), f(n)=0
if(n mod 4=0), f(n)=n
- 盗一下某人的证明:
证明:
我们先来考虑f(2k,2k+1−1)
从2k到2k+1−1这2k个数,最高位的一个数为2k;
若有k>=1,则2k为偶数,将这2k个数的最高位去掉,异或和不变
因此f(2k,2k+1−1)=f(2k−2k,2k+1−2k−1)=f(0,2k−1)
因而存在f(0,2k+1−1)=f(0,2k−1)xorf(2k,2k+1−1)=0
即f(0,2k−1)=0
对于,f(0,n),n≥4设n二进制表示的最高位1在第k位k>=2;
f(0,n)=f(0,2k−1)xorf(2k,n)=f(2k,n)
对于2k到n这n−2k+1个数,最高位共有m=n−2k+1个1,去除最高位的1
当n为奇数时,m为偶数此时有f(0,n)=f(2k,n)=f(0,n−2k)∣2k
由于n−2k与n奇偶性相同,递推上面的公式可得f(0,n)=f(0,n−2k−2k−1−2k−2⋯−22)=f(0,n%4)
当n%4=1时f(0,n)=f(0,1)=1
当n%4=3时f(0,n)=f(0,3)=0
当n为偶数时,m为奇数,因而f(0,n)=f(2k,n)=f(0,n−2k)xor2k
也相当于最高位不变,递推公式可得
f(0,n)=f(0,n%4)xor2kxor n[k]∗2k−1xor⋯ n[2]∗22
n[k]表示n的二进制表示的第k位
显然当n为偶数时 f(0,n)的二进制从最高位到第3位和n的二进制表示相同
此时我们只需要判断第二位
当n%4=0时f(0,n)=n
当n%4=2时f(0,n)=n+1
综上所述:
f(0,n)=f(1,n)⎩⎪⎪⎪⎨⎪⎪⎪⎧n n%4=01 n%4=1n+1n%4=20 n%4=3