Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define MAX 1 << 17
- #define LOGN 17
- #define MOD 1000000007
- using namespace std;
- typedef long long ll;
- vector<ll> ORANDO(vector<ll> &a) {
- vector<ll> ans(MAX, 0);
- for (int i = 0; i < MAX; i++){
- for (int j = i-1; j >= 0; j = (j-1)&i){
- ll mult = (a[i^j]*a[j])%MOD;
- ans[i] = (ans[i] + mult)%MOD;
- if(j == 0) break;
- }
- }
- return ans;
- }
- int T[3][2][2][2] = {
- { { {1, 1}, {1, -1} }, { {1, 1}, {1, -1} } }, /// xor
- { { {0, 1}, {1, 1} }, { {-1, 1}, {1, 0} } }, /// and
- { { {1, 1}, {1, 0} }, { {0, 1}, {1, -1} } } /// or
- };
- void FFT(vector<ll> &a, int op, bool inverse = false) {
- ll u1 = T[op][inverse][0][0], v1 = T[op][inverse][0][1];
- ll u2 = T[op][inverse][1][0], v2 = T[op][inverse][1][1];
- for(int b = 0; b < LOGN; b++)
- for(int i = 0; i < MAX; i++)
- if((i & (1 << b)) == 0) {
- ll u = a[i], v = a[i + (1 << b)];
- a[i] = ((u*u1)%MOD + (v*v1)%MOD)%MOD;
- a[i + (1 << b)] = ((u*u2)%MOD + (v*v2)%MOD)%MOD;
- }
- if (op == 0 && inverse)
- for (int i=0; i<a.size(); i++)
- a[i] >>= LOGN;
- }
- /// op is 0 for XOR, 1 for AND, 2 for OR
- vector<ll> convolution(vector<ll> a, vector<ll> b, int op) {
- FFT(a, op, false);
- FFT(b, op, false);
- for(int i=0; i<a.size(); i++)
- a[i] = (a[i] * b[i])%MOD;
- FFT(a, op, true);
- return a;
- }
- ll fibo[MAX];
- void build(){
- fibo[1] = 1LL;
- for(ll i = 2LL; i < MAX; i++) fibo[i] = (fibo[i-1]+fibo[i-2])%MOD;
- }
- void print(vector<ll> &a, int sz){
- for(int i = 0; i < sz; i++) cout << a[i] << " ";
- cout << endl;
- }
- int main(){
- int n; scanf("%d", &n);
- vector<ll> arr(MAX, 0);
- for(int i = 0; i < n; i++){
- ll x;scanf("%lld", &x);
- arr[x]++;
- }
- build();
- vector<ll> oris = ORANDO(arr);
- vector<ll> xoris = convolution(arr, arr, 0); // RIP XORIS
- for(int i = 0; i < oris.size(); i++) oris[i] = (fibo[i]*oris[i])%MOD;
- for(int i = 0; i < xoris.size(); i++) xoris[i] = (xoris[i]*fibo[i])%MOD;
- for(int i = 0; i < arr.size(); i++) arr[i] = (fibo[i]*arr[i])%MOD;
- vector<ll> andis = convolution(oris, arr, 1);
- vector<ll> ans = convolution(andis, xoris, 1);
- //print(ans, 50);
- ll resp = 0LL;
- for(ll i = 1LL; i <= (1 << 17); i *= 2LL) {
- if(ans[i] != 0) resp = (resp+ans[i])%MOD;
- }
- printf("%lld\n", resp);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement