When I was doing ACM, I often encountered a modulo operation, and the modulo operation was the most slow in arithmetic operations (basically in the current computer hardware ).
The power modulo of 1 to 2 (2 ^ k) is equivalent to the bitwise operation of (2 ^ k-1 ).
For example, bitwise AND operation can be performed on Binary bits because the computer is represented in binary.
N % 8 = (n & 7) // Since the C language modulo operation returns a negative number, when n is a negative number, they are in the same-mode relationship.
2 There are often some Recursive formulas, which are the addition and post-modulus relations. In this case, we can use the characteristics of a limited range to convert the modulus into addition and subtraction.
// For example dp [0] = dp [1] = 1dp [I] = (dp [I-1] + dp [I-2]) % MOD; // note that the dp array is a positive number, and the two elements are added in the range of [* MOD. // The formula can be rewritten to int madd [2] = {0, MOD}, r; r = dp [I-1] + dp [I-2]-MOD; dp [I] = r + madd [(unsigned) (r)> 31];
3. the results of some questions are high-precision (the type provided by the language cannot be expressed and must be simulated using arrays ), generally, a 32bit int is used to represent the number of 10 ^ 9 hexadecimal values.
This is really intuitive and also in line with our decimal intuition, but it is very slow to perform modulo and Division operations every time the carry is carried.
We can consider using the 2 ^ 30 hexadecimal notation. In this way, we use the "shift" and "bitwise AND" operations to greatly increase the running speed.
Of course, there will also be a problem in the end, that is, the 2 ^ 30 hexadecimal notation cannot be printed directly. In this case, you also need to convert the 2 ^ 30 hexadecimal notation to the 10 ^ 9 hexadecimal notation and then output it. Since it is often printed only once, it is basically free of time.
// Example 2 ^ 30 addition # define Len 5 // use several int # define P2 30 for each precision // 2 ^ P2 hexadecimal # define m2 (1 <P2) -1) // mask used for modulo operation // high precision C = a + binlinevoid add (int * a, int * B, int * C) {c [0] = A [0] + B [0]; for (INT I = 1; I <Len; ++ I) {c [I] = A [I] + B [I] + (C [I-1]> P2); C [I-1] & = m2 ;}}
The following code is converted from 2 ^ 30 to 10 ^ 9 and printed:
#define M10 1000000000void convert_print( int* d2 ) { int d10[LEN] = {0}; int i = LEN - 1, j, k = 0; LL r; while( i >= 0 ) { while( d2[i] == 0 ) --i; if( i < 0 ) break; for( r = 0, j = i; j >= 0; --j ) { r = ( ( r << P2 ) + d2[j] ); d2[j] = r / M10; r %= M10; } d10[k++] = r; } char buf[LEN*9+1]; int pos = 0; for( i = LEN - 1; i > 0; --i ) if( d10[i] ) break; pos += sprintf( buf + pos, "%d", d10[i] ); for( --i; i >= 0; --i ) pos += sprintf( buf + pos, "%09d", d10[i] ); buf[pos] = 0; puts( buf );}