1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| #include <cstdio> using namespace std; typedef long long LL; template <class Type> void read(Type &x) { char c; bool flag = false; while ((c = getchar()) < '0' || c > '9') c == '-' && (flag = true); x = c - '0'; while ((c = getchar()) >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0'; flag && (x = ~x + 1); } template <class Type> void write(Type x) { x < 0 && (putchar('-'), x = ~x + 1); x > 9 && (write(x / 10), 0); putchar(x % 10 + '0'); } const int N = 17, M = 1 << N, mod = 1e9 + 7, inv2 = 5e8 + 4; int n, fib[M], cnt[M], s[M], A[M], B[M], C[M]; namespace SolveAB { int f[N + 1][M], g[N + 1][M]; void fwt (int *x, int op) { for (int mid = 1; mid < M; mid <<= 1) for (int i = 0; i < M; i += mid << 1) for (int j = 0; j < mid; j++) (x[i | j | mid] += x[i | j] * op) %= mod; } void main () { for (int i = 0; i < M; i++) f[cnt[i]][i] = s[i]; for (int i = 0; i <= N; i++) fwt(f[i], 1); for (int i = 0; i <= N; i++) for (int j = 0; i + j <= N; j++) for (int k = 0; k < M; k++) (g[i + j][k] += (LL)f[i][k] * f[j][k] % mod) %= mod; for (int i = 0; i <= N; i++) fwt(g[i], -1); for (int i = 0; i < M; i++) A[i] = g[cnt[i]][i]; } } namespace SolveC { void main () { for (int i = 0; i < M; i++) B[i] = s[i]; } } namespace SolveDE { void fwt (int *x, int op) { for (int mid = 1; mid < M; mid <<= 1) for (int i = 0; i < M; i += mid << 1) for (int j = 0; j < mid; j++) { int p = x[i | j], q = x[i | j | mid]; x[i | j] = (LL)(p + q) * op % mod, x[i | j | mid] = (LL)(p - q) * op % mod; } } void main () { for (int i = 0; i < M; i++) C[i] = s[i]; fwt(C, 1); for (int i = 0; i < M; i++) C[i] = (LL)C[i] * C[i] % mod; fwt(C, inv2); } } namespace Merge { void fwt (int *x, int op) { for (int mid = 1; mid < M; mid <<= 1) for (int i = 0; i < M; i += mid << 1) for (int j = 0; j < mid; j++) (x[i | j] += x[i | j | mid] * op) %= mod; } void main () { fwt(A, 1), fwt(B, 1), fwt(C, 1); for (int i = 0; i < M; i++) A[i] = (LL)A[i] * B[i] % mod * C[i] % mod; fwt(A, -1); int res = 0; for (int i = 1; i < M; i <<= 1) (res += A[i]) %= mod; write((res + mod) % mod); } } int main () { fib[1] = 1, cnt[1] = 1; for (int i = 2; i < M; i++) { cnt[i] = cnt[i >> 1] + (i & 1); fib[i] = (fib[i - 2] + fib[i - 1]) % mod; } read(n); for (int a; n; n--) read(a), s[a]++; SolveAB::main(), SolveC::main(), SolveDE::main(); for (int i = 0; i < M; i++) A[i] = (LL)A[i] * fib[i] % mod, B[i] = (LL)B[i] * fib[i] % mod, C[i] = (LL)C[i] * fib[i] % mod; Merge::main(); return 0; }
|