As a tradition, every year before IOI all the members of Natalia Fan Club are invited to Malek Dance Club to have a fun night together. Malek Dance Club has 2n members and coincidentally Natalia Fan Club also has 2nmembers. Each member of MDC is assigned a unique id i from 0 to 2n - 1. The same holds for each member of NFC.
One of the parts of this tradition is one by one dance, where each member of MDC dances with a member of NFC. A dance pair is a pair of numbers (a, b) such that member a from MDC dances with member b from NFC.
The complexity of a pairs' assignment is the number of pairs of dancing pairs (a, b) and (c, d) such that a < c andb > d.
You are given a binary number of length n named x. We know that member i from MDC dances with member from NFC. Your task is to calculate the complexity of this assignment modulo 1000000007 (109 + 7).
Expression denotes applying «XOR» to numbers x and y. This operation exists in all modern programming languages, for example, in C++ and Java it denotes as «^», in Pascal — «xor».
注意到n很小,如果能够求出递推公式,问题将很容易得到解决。
x长度为n,f(x)表示complexity,显然f(0)=0,f(1)=1。当n>1时,f(0x)和f(1x)可由f(x)推出。
(1)求f(0x): i 分别取 0,1,...,2^n-1,j分别取2^n,...,2^(n+1) - 1, 统计(i,i xor 0x)与(j, j xor 0x)能组成多少对,注意j xor 0x的第一位是1,而i xor 0x的第一位是0,故而 j xor 0x > i xor 0x,而 j > i,故(i,i xor 0x)与(j, j xor 0x)不能配对。统计(j, j xor 0x)内部能组成多少对,所有j的第一位相同, 导致j xor 0x的第一位都相同,故而j的第一位是没有比较意义的,去掉没有影响,故(j, j xor 0x)的配对数为f(x)。所以f(0x)=2f(x)
(2)求f(1x): i 分别取 0,1,...,2^n-1,j分别取2^n,...,2^(n+1) - 1, 统计(i,i xor 1x)与(j, j xor 1x)能组成多少对,注意j xor 1x的第一位是0,而i xor 1x的第一位是1,故而 i xor 1x > j xor 1x ,而 i < j,故(i,i xor 1x)与(j, j xor 1x)之间能产生2^(2n)对。统计(j, j xor 0x)内部能组成多少对,所有j的第一位都相同, 导致j xor 1x的第一位都相同,故而j的第一位是没有比较意义的,去掉没有影响,故(j, j xor 0x)的配对数为f(x)。所以f(1x)=2f(x)+2^(2n)
综上:
- f(0x) = 2f(x)
- f(1x) = 2f(x) + 2^2n
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <map> 5 #include <vector> 6 #include <cstdio> 7 #include <cmath> 8 #include <cstring> 9 using namespace std; 10 11 char x[101]; 12 const int m = 1000000007; 13 int n; 14 15 long long POW(long long a, long long b) 16 { 17 if(!b) return 1; 18 long long c = POW(a, b>>1); 19 c = (c * c) % m; 20 if(b & 1) 21 { 22 c = (c * a) % m; 23 } 24 return c; 25 } 26 27 int f(int k) 28 { 29 if(k == n - 1) 30 { 31 if(x[k] == '0') return 0; 32 else return 1; 33 } 34 if(x[k] == '0') return (2 * f(k + 1)) % m; 35 else return ((2 * f(k + 1)) % m + POW(4, n - k - 1)) % m; 36 } 37 38 int main() 39 { 40 while(scanf("%s", x) != EOF) 41 { 42 n = strlen(x); 43 printf("%d ", f(0)); 44 } 45 return 0; 46 }