我也不知道這是哪一題 - FWT

感謝QLS的點撥和HLS的大腿


Archaeologists have made a discovery on the Temple of Topology. The temple was once used as a place for ritual ceremony thousands of years ago. Among the relics that were unearthed, a scroll of parchment raised the interest of scientists. The parchment contained many numbers written in ancient symbols.

By decrypting the words carved on a stone, scientists know that these numbers form an interesting set of integers satisfying the following two properties:

  1. Bitwise AND any number of integers from the set result in an integer in that set again.
  2. Bitwise OR any number of integers from the set result in an integer in that set again.

As the parchment is extremely old, some part of it were broken and the numbers were lost. Now you job is to complete the original set from the remaining integers such that the size of the set is as small as possible.

Input

The input contains several test cases. The total number of test cases is less than 11001100. Each test case begins with a line containing an integer n (n > 1)n(n>1). The following line contains nn integers a_i (0 \le a_i < 2^{16})ai(0ai<216), the remaining integers on the parchment. The integers are distinct.

Output

For each test case, output one line containing a single integer, the minimal number of additional integers to make the set complete. If these numbers are already a complete set, print 00.

樣例輸入

4
5
0 1 3 5 7
2
2 4
3
3 7 11
3
1 2 4

樣例輸出

Case #1: 0
Case #2: 2
Case #3: 1
Case #4: 5
#include<bits/stdc++.h>
using namespace std;
const int N = 1<<16;
const int mod = 1e9+7;
void FWT_A(int a[],int n)
{
    for(int d=1; d<n; d<<=1)
        for(int m=d<<1,i=0; i<n; i+=m)
            for(int j=0; j<d; j++)
            {
                int x=a[i+j],y=a[i+j+d];
                a[i+j]=x+y;
            }
}
void FWT_O(int a[],int n)
{
    for(int d=1; d<n; d<<=1)
        for(int m=d<<1,i=0; i<n; i+=m)
            for(int j=0; j<d; j++)
            {
                int x=a[i+j],y=a[i+j+d];
                a[i+j+d]=x+y;
            }
}
void UFWT_A(int a[],int n)
{
    for(int d=1; d<n; d<<=1)
        for(int m=d<<1,i=0; i<n; i+=m)
            for(int j=0; j<d; j++)
            {
                int x=a[i+j],y=a[i+j+d];
                a[i+j]=x-y;
            }
}
void UFWT_O(int a[],int n)
{
    for(int d=1; d<n; d<<=1)
        for(int m=d<<1,i=0; i<n; i+=m)
            for(int j=0; j<d; j++)
            {
                int x=a[i+j],y=a[i+j+d];
                a[i+j+d]=y-x;
            }
}
void solve(int a[],int n)
{
    FWT_A(a,n);
    for(int j = 0; j < 4; j++)
    {
        for(int i=0; i<n; i++) a[i]=1LL*a[i]*a[i]%mod;
    }
    UFWT_A(a,n);
    FWT_O(a,n);
    for(int j = 0; j < 4; j++)
    {
        for(int i=0; i<n; i++) a[i]=1LL*a[i]*a[i]%mod;
    }
    UFWT_O(a,n);
}
int main()
{
    int a[N] = {0};
    int n;
    int t;
    cin >> t;
    for(int k = 1; k <= t; k++)
    {
        cin >> n;
        for(int i = 0; i < N; i++)a[i]=0;
        int m = 1;
        for(int i = 0; i < n; i++)
        {
            int x;
            scanf("%d",&x);
            a[x] = 1;
            while(m<=x) m<<=1;
        }
        solve(a,m);
        int cnt = 0;
        for(int i = 0; i < m; i++)
            if(a[i])
                cnt++;
        printf("Case #%d: %d\n",k,cnt-n);
    }
}


發佈了77 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章