1. 程式人生 > >2018牛客網暑期ACM多校訓練營(第九場)A -Circulant Matrix(FWT)

2018牛客網暑期ACM多校訓練營(第九場)A -Circulant Matrix(FWT)

html ++ oid logs sync const stdout i++ scan

分析

大佬說看樣例就像和卷積有關。

把題目化簡成a*x=b,這是個xor的FWT。

FWT的講解請看:https://www.cnblogs.com/cjyyb/p/9065615.html

那麽要求的是x,所以我們得逆著來,則對b進行IFWT,對a FWT,然後c=b/a,於是x=FWT(c).

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include 
<cmath> #include <ctime> #include <vector> #include <queue> #include <map> #include <stack> #include <set> #include <bitset> using namespace std; typedef long long ll; typedef unsigned long long ull; #define ms(a, b) memset(a, b, sizeof(a)) #define
pb push_back #define mp make_pair #define pii pair<int, int> #define IOS ios::sync_with_stdio(0);cin.tie(0); #define random(a, b) rand()*rand()%(b-a+1)+a #define pi acos(-1.0) const ll INF = 0x3f3f3f3f3f3f3f3fll; const int inf = 0x3f3f3f3f; const int maxn = 3e5+10; const int maxm = 1e5+10;
const int mod = 1e9+7; ll qpow(ll a,ll b){ ll res=1; while(b){ if(b&1) res=res*a%mod; b>>=1; a=a*a%mod; } return res; } ll inv = 500000004; void IFWT(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)%mod*inv%mod; a[i+j+d]=(x-y+mod)%mod*inv%mod; } } void FWT(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)%mod; a[i+j+d]=(x-y+mod)%mod; } } int a[maxn],b[maxn]; int main(){ #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("output.txt", "w", stdout); #endif int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<n;i++) scanf("%d",&b[i]); FWT(a,n); IFWT(b,n); for(int i=0;i<n;i++) a[i]=b[i]*qpow(a[i],mod-2)%mod; FWT(a,n); for(int i=0;i<n;i++) cout<<a[i]<<endl; return 0; }

2018牛客網暑期ACM多校訓練營(第九場)A -Circulant Matrix(FWT)