链接:https://www.nowcoder.com/acm/contest/147/A
来源:牛客网
Niuniu has recently learned how to use Gaussian elimination to solve systems of linear equations.
Given n and a[i], where n is a power of 2, let's consider an n x n matrix A.
The index of A[i][j] and a[i] are numbered from 0.
The element A[i][j] satisfies A[i][j] = a[i xor j],
https://en.wikipedia.org/wiki/Bitwise_operation#XOR
Let p = 1000000007.
Consider the equation A x = b (mod p)
where A is an n x n matrix, and x and b are both n x 1 row vector.
Given n, a[i], b[i], you need to solve the x.
For example, when n = 4, the equations look like
A[0][0]*x[0] + A[0][1]*x[1] + A[0][2]*x[2] + A[0][3]*x[3] = b[0] (mod p)
A[1][0]*x[0] + A[1][1]*x[1] + A[1][2]*x[2] + A[1][3]*x[3] = b[1] (mod p)
A[2][0]*x[0] + A[2][1]*x[1] + A[2][2]*x[2] + A[2][3]*x[3] = b[2] (mod p)
A[3][0]*x[0] + A[3][1]*x[1] + A[3][2]*x[2] + A[3][3]*x[3] = b[3] (mod p)
and the matrix A can be decided by the array a.
It is guaranteed that there is a unique solution x for these equations.
输入描述:
The first line contains an integer, which is n.
The second line contains n integers, which are the array a.
The third line contains n integers, which are the array b.
1 <= n <= 262144
p = 1000000007
0 <= a[i] < p
0 <= b[i] < p
输出描述:
The output should contains n lines.
The i-th(index from 0) line should contain x[i].
x[i] is an integer, and should satisfy 0 <= x[i] < p.
示例1
输入
4 1 10 100 1000 1234 2143 3412 4321
输出4
3 2 1
解析 给出 已知A b 求 x
上式可以转化成 由于 i^j^j=i
所以原式等式 直接套fwt_xor 板子
代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,n) for (int i=a;i<n;i++) 4 #define per(i,a,n) for (int i=n-1;i>=a;i--) 5 #define pb push_back 6 #define mp make_pair 7 #define all(x) (x).begin(),(x).end() 8 #define fi first 9 #define se second 10 #define SZ(x) ((int)(x).size()) 11 typedef vector<int> VI; 12 typedef long long ll; 13 typedef pair<int,int> PII; 14 const ll mod=1000000007; 15 const int maxn = 3e6+10; 16 ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} 17 // head 18 19 int a[maxn],b[maxn]; 20 void FWT_or(int *a,int N,int opt) 21 { 22 for(int i=1;i<N;i<<=1) 23 for(int p=i<<1,j=0;j<N;j+=p) 24 for(int k=0;k<i;++k) 25 if(opt==1)a[i+j+k]=(a[j+k]+a[i+j+k])%mod; 26 else a[i+j+k]=(a[i+j+k]+mod-a[j+k])%mod; 27 } 28 void FWT_and(int *a,int N,int opt) 29 { 30 for(int i=1;i<N;i<<=1) 31 for(int p=i<<1,j=0;j<N;j+=p) 32 for(int k=0;k<i;++k) 33 if(opt==1)a[j+k]=(a[j+k]+a[i+j+k])%mod; 34 else a[j+k]=(a[j+k]+mod-a[i+j+k])%mod; 35 } 36 void FWT_xor(int *a,int N,int opt) //opt=1 正变换 opt=-1 逆变换 37 { 38 ll inv2=powmod(2,mod-2); 39 for(int i=1;i<N;i<<=1) 40 for(int p=i<<1,j=0;j<N;j+=p) 41 for(int k=0;k<i;++k) 42 { 43 int X=a[j+k],Y=a[i+j+k]; 44 a[j+k]=(X+Y)%mod;a[i+j+k]=(X+mod-Y)%mod; 45 if(opt==-1)a[j+k]=1ll*a[j+k]*inv2%mod,a[i+j+k]=1ll*a[i+j+k]*inv2%mod; 46 } 47 } 48 int main() 49 { 50 int n; 51 scanf("%d",&n); 52 for(int i=0;i<n;i++) 53 scanf("%d",&a[i]); 54 for(int i=0;i<n;i++) 55 scanf("%d",&b[i]); 56 FWT_xor(a,n,1);FWT_xor(b,n,1); 57 for(int i=0;i<n;i++) 58 { 59 b[i]=b[i]*powmod(a[i],mod-2)%mod; // b/a 60 } 61 FWT_xor(b,n,-1); //再逆变换 62 for(int i=0;i<n;i++) 63 printf("%d ",b[i]); 64 }