P4932 browser (count the number of binary 1)

P4932 browser

There \ (n-\) number, \ (x_1, x_2, \ cdots, x_n \) , ask for how many \ ((U, V) \) , so \ (x_u \ operatorname {xor} x_v \) of an odd number of binary representation \ (1 \)

Six input integer, \ (n-, A, B, C, D, x_0 \) .
Weight of each point is a need to generate the following manner.
\ (x_i = (ax_ {i -1} ^ 2 + bx_ {i-1} + c) \ bmod d \)

\ (n \ le 10 ^ 7 , \ max (x_i) \ le 10 ^ 9, a, b, c, d, x_0 \) in \ (int \) range


Title-bit computing, you can consider What is the relationship of certain amount of numbers before and after the operation
such as this problem can be found only \ (x_u, x_v \) in binary \ (1 \) the number one odd one even, \ (x_u \ operatorname {xor} x_v \) binary with only odd number \ (1 \)
may be provided \ (x_u, x_v \) binary \ (1 \) have \ (K \) bits coincide, i.e. this says \ (K \) two bits are the number \ (1 \)
for exclusive-oR operation, only two different numbers is a bit \ (1 \) , they have \ (\ text {+} even number \ text {odd} -2k \) different digits, in fact, are \ (1 \) digits are common minus \ (1 \) that \ (k \) position
then is the \ (\ text {even number } + \ text {odd} - \ text {even-numbered} = \ text {odd} \)


So now consider how to quickly find a binary number in \ (1 \) number

First, it is clear that there is a way

inline int cnt1(int x){
	reg int ret=0;
	while(x) ret+=x&1,x>>=1;
	return ret;
}

A is a number, the complexity of the \ (O (\ log x)
\) if this problem with this method, \ (O (n-\ log X) \) , is doing \ (3 \ cdot 10 ^ 8 \) , but still not running 1.5s last two points, it may be constant too large


Next there is a slightly optimized method

inline int cnt2(int x){
	reg int ret=0;
	while(x){
		ret++;
		x^=(x&(-x));
	}
	return ret;
}

The results of each increment, and then remove the last of a binary \ (1 \)
complexity and \ (X \) the number of binary numbers related, but also the worst \ (O (\ log x)
\) how to remove the last \ (1 \) storage, and the number of computer-related

Original code

Original code is a binary representation of the number, plus the sign bit, the sign bit is \ (0 \) represents an integer, otherwise it is negative
but in a time of negative numbers, each additional bit, but the value of the number will be reduced, can not be completed addition operation
may of course be considered then take its absolute value symbol or the like, but for the most basic addition such computer operation, to be too cumbersome

Inverted

Positive anti-code number is itself, a negative anti-code is in addition to the sign bit, every invert the result of
this would resolve the problem of the addition of the respective positive and negative numbers, saying "their" because they can not cross \ (0 \)
since \ (0 + \) is expressed as \ (0000 \) , and \ (- 0 \) is expressed as \ (1111 \) , so that when the calculation, each time across \ (0 \) , so that the results are less First, to cite two examples represent themselves try to use inverted know

Complement

So with complement, or complement their own positive, negative complement its anti-code plus a
then perfect solution to the problem of addition
and \ (1111 \) this one will be no counted (we four-digit binary number, for example), so let this bit indicates \ (- 2 ^ 3 \)
which is why most of the range of data types represent a \ ([- 2 ^ n, 2 ^ n) \)

After the pull can understand that the above method, after become negative, corresponds to each bit of the anti, and then add a
hypothesis that \ (X = \ cdots 100 \ cdots \) , this write \ ( 1 \) is the last one , that is, to get rid of \ (1 \) , then invert later became \ (\ cdots011 \ cdots \)
because the back negated the results of all \ (1 \) , plus one, will carry , it becomes a \ (\ cdots100 \ cdots \)
then do the operation and the original number, you come to the one who \ (1 \) , with the exclusive or remove the line

This method has been through this problem


But there is a way to even better

inline int cnt3(reg int x){    
    x=(x&0x55555555)+((x>>1)&0x55555555);
    x=(x&0x33333333)+((x>>2)&0x33333333);
    x=(x&0x0f0f0f0f)+((x>>4)&0x0f0f0f0f);
    x=(x&0x00ff00ff)+((x>>8)&0x00ff00ff);
    x=(x&0x0000ffff)+((x>>16)&0x0000ffff);
    return x;   
}
inline int cnt4(reg LL x){    
    x=(x&0x5555555555555555ll)+((x>>1)&0x5555555555555555ll);
    x=(x&0x3333333333333333ll)+((x>>2)&0x3333333333333333ll);
    x=(x&0x0f0f0f0f0f0f0f0fll)+((x>>4)&0x0f0f0f0f0f0f0f0fll);
    x=(x&0x00ff00ff00ff00ffll)+((x>>8)&0x00ff00ff00ff00ffll);
    x=(x&0x0000ffff0000ffffll)+((x>>16)&0x0000ffff0000ffffll);
    x=(x&0x00000000ffffffffll)+((x>>32)&0x00000000ffffffffll);
    return x;
}

cnt3Is a process \ (int \) , and cnt4is a process \ (long \ space long \) is
can be seen, this method is \ (O (\ log \ log
x) \) In fact, there is a closer look \ ( O (. 1) \) , but use a modulo operation, so that each may actually run up faster and harder than this understanding

8 with a binary number, for example, \ (\ texttt {10111001} \) , in fact, more bits, too
\ (\ texttt {0x55} \ ) binary is \ (\ texttt {01010101} \ )

Therefore, and with it, it retains \ (1,3,5,7 \) at position \ (1 \) is \ (\ texttt {00010001} \
) If this binary left one, then and with it, then it is surely retained \ (2,4,6,8 \) is on \ (1 \) , respectively, and then put it into the \ (1,3,5,7 \) on the position
left one after another with the result: \ (\ texttt {01010100} \)
and just that \ (\ texttt {00010001} \ ) after the addition was complete results: \ (\ texttt {01 10 01} 01 \)
where it two a break, you can easily find, for every two, the two binary number, which is on two \ (1 \) number

Then continue to observe, discover \ (\ texttt {0x33} \ ) binary is \ (\ texttt {0011 0011}
\) then \ (\ texttt {01 10 01 01} \ operatorname {and} \ texttt {00 11 00 11 } = \ texttt {00 10 00
01} \) this mean? Of course, if each segment, then two minutes, retention \ (3 \) in the paragraph \ (1 \)
Similarly, two left and then, is reserved \ (2,4 \) segments \ (1 \ ) and placed \ (3 \) upper section
coupled together, the result is \ (\ texttt {0011 0010}
\) in this case, it four period, the first four binary number is a front nibble how much \ (1 \) , the last four, too

Now almost I understand, in fact, this approach is to continue to adjacent bits \ (1 \) the number of merged into a larger range, finally, is the whole \ (x \) represents \ (x \) in \ (1 \) number of
returns \ (X \)

However, this also less than half a second faster than the total time on a method of

Put the complete code

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
	register int x=0;register int y=1;
	register char c=std::getchar();
	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
int n;
inline int cnt1(int x){
	reg int ret=0;
	while(x) ret+=x&1,x>>=1;
	return ret;
}
inline int cnt2(int x){
	reg int ret=0;
	while(x){
		ret++;
		x^=(x&(-x));
	}
	return ret;
}
inline int cnt3(reg int x){    
    x=(x&0x55555555)+((x>>1)&0x55555555);
    x=(x&0x33333333)+((x>>2)&0x33333333);
    x=(x&0x0f0f0f0f)+((x>>4)&0x0f0f0f0f);
    x=(x&0x00ff00ff)+((x>>8)&0x00ff00ff);
    x=(x&0x0000ffff)+((x>>16)&0x0000ffff);
    return x;   
}
inline int cnt4(reg LL x){    
    x=(x&0x5555555555555555ll)+((x>>1)&0x5555555555555555ll);
    x=(x&0x3333333333333333ll)+((x>>2)&0x3333333333333333ll);
    x=(x&0x0f0f0f0f0f0f0f0fll)+((x>>4)&0x0f0f0f0f0f0f0f0fll);
    x=(x&0x00ff00ff00ff00ffll)+((x>>8)&0x00ff00ff00ff00ffll);
    x=(x&0x0000ffff0000ffffll)+((x>>16)&0x0000ffff0000ffffll);
    x=(x&0x00000000ffffffffll)+((x>>32)&0x00000000ffffffffll);
    return x;
}
int main(){
	n=read();reg int a=read(),b=read(),c=read(),d=read(),x=read();
	a%=d;b%=d;c%=d;x%=d;
	reg int even=0,odd=0;
	while(n--){
		x=((1ll*a*x%d*x%d)+(1ll*b*x%d)+c)%d;
		(cnt3(x)&1)?odd++:even++;
	}
	std::printf("%lld",1ll*odd*even);
	return 0;
}

Guess you like

Origin www.cnblogs.com/suxxsfe/p/12651569.html