[Training] FWT basic exercises

The meaning of problems

Gives the length of n binary numbers and k 20 is each time a query is given binary number, Q pick number n from the number k (no duplication) or bitwise combination can contain the number of query. Figures are less 5E5,1s.


 

Think

2 ^ 20 calculates forced answer, then O (1) query.

Seen by bit or two arrays of FWT can be fused into a new array. Suppose F. K denotes the k pick all possible numbers can be composed of the tub , A is the original bucket array, seen F. K [I] = (F. K. 1- ORed FWT A) [i] - ( k-1) F. K-. 1 [I], the purpose behind the subtraction subtracts the repeated selection portion.

FWT then actually observed linear transformation, so F. K [I] may be previously multiplied by the last calculated conveniently k. So long as the beginning of a number of combinations can be multiplied.

According to the last bit and FWT available all the answers. The total complexity of O (nlogn).


 

Code

 1 #pragma GCC optimize 2
 2 #include<bits/stdc++.h>
 3 #define mod 1000000007
 4 using namespace std;
 5 typedef long long int ll;
 6 const int maxn=1E6+5E5+5;
 7 const int LEN=4;
 8 const int G=1<<LEN;
 9 ll n,k,m,a[maxn],b[maxn],c[maxn],d[maxn];
10 ll fac[maxn],inv[maxn];
11 string str;
12 inline int get(string str)
13 {
14     int sum=0;
15     for(int i=0;i<LEN;++i)
16         sum=sum*2+str[i]-'0';
17     return sum;
18 }
19 ll qpow(ll x,ll y)
20 {
21     ll ans=1,base=x;
22     while(y)
23     {
24         if(y&1)
25             ans=ans*base%mod;
26         base=base*base%mod;
27         y>>=1;
28     }
29     return ans;
30 }
31 void init()
32 {
33     fac[0]=1;
34     for(int i=1;i<=500000;++i)
35         fac[i]=fac[i-1]*i%mod;
36     inv[500000]=qpow(fac[500000],mod-2);
37     for(int i=500000-1;i>=0;--i)
38         inv[i]=inv[i+1]*(i+1)%mod;
39 }
40 void FWT(ll*A,int t1,int t2)
41 {
42     for(int len=2;len<=G;len<<=1)
43         for(int i=0;i<G/len;++i)
44             for(int j=0;j<len/2;++j)
45             {
46                 ll a=A[i*len+j],b=A[i*len+j+len/2];
47                 A[i*len+j]=(a+b*t1)%mod;
48                 A[i*len+j+len/2]=(b+a*t2)%mod;
49             }
50 }
51 template<class T>void copy(T*a,T*b,int x)
52 {
53     for(int i=0;i<x;++i)
54         a[i]=b[i];
55 }
56 int main()
57 {
58     ios::sync_with_stdio(false);
59     init();
60     cin>>n>>k>>m;
61     for(int i=1;i<=n;++i)
62     {
63         cin>>str;
64         ++a[get(str)];
65     }
66     copy(c,a,G);
67     FWT(a,0,1);
68     for(int i=0;i<G;++i)
69     {
70         if(a[i]>=k)
71             a[i]=fac[a[i]]*inv[a[i]-k]%mod;
72         else
73             a[i]=0;
74     }
75     FWT(a,0,-1);
76     /*
77     for(int i=2;i<=k;++i)
78     {
79         copy(d,a,G);
80         FWT(a,0,1);
81         copy(b,c,G);
82         FWT(b,0,1);
83         for(int j=0;j<G;++j)
84             a[j]=a[j]*b[j]%mod;
85         FWT(a,0,-1);
86         for(int j=0;j<G;++j)
87             a[j]=(a[j]-d[j]*(i-1)+mod)%mod;
88     }
89     */
90     FWT(a,1,0);
91     while(m--)
92     {
93         cin>>str;
94         cout<<a[get(str)]*inv[k]%mod<<endl;
95     }
96     return 0;
97 }
View Code

 

Guess you like

Origin www.cnblogs.com/GreenDuck/p/11104630.html