第一道自己寫的fft......
不知為啥這題在網上找不到題解......真是麻煩,害得我推了半天......
還是寫個簡要題解吧......
首先把s和t拆成序列,a~z分別對應成1~26,?是0,設拆成的兩個序列分別為a和b。
如果從i開始可以s匹配上t,那麼就有
\begin\sum_^[|a_-b_j|=0 \space or \space b_j=0]=m\end
換乙個等價寫法:
\begin\sum_^(a_-b_j)^2 b_j=0\end
求出所有i對應的值就可以得知每一位是否匹配了。
展開之後發現並沒有什麼用,這個式子只能$o(n^2)$計算,還不如樸素匹配呢,這玩意兒有個卵用啊(╯‵□′)╯︵┻━┻
嘗試把t反轉,原式變為
\begin\sum_^(a_i-b_)^2 b_\end
展開得\begin\sum_^a_^2 b_-2a_b_^2+b_^3\end
有沒有發現這個式子看著有點眼熟......
前兩項下標之和都是i+m-1,因此可以看成乙個卷積形式,而令最後一項再卷上乙個各項全為1的序列(顯然不影響結果是吧......),也是卷積,而下標之和是i+m-1,因此定義我們得到的結果為
\beginc_=\sum_^a_^2 b_-2a_b_^2+1b_^3\end
令$d_i=a_i^2,e_i=b_i^2,f_i=b_i^3,i_i=1$,再寫成卷積形式就是
\beginc=d*b-2a*e+f*i\end
分別求出三個卷積之後加一下就行了,fft加速卷積即可,複雜度$o(nlogn)$。
然而常數大如狗,跑的比bitset慢到不知哪兒去了
求出三個卷積的和之後掃一遍判斷哪些i對應的$c_$是0,是的話說明兩串在i位置匹配,否則不匹配。
1 #include2 #include3 #include4 #include5view codeusing
namespace
std;
6const
int maxn=270010;7
const
double pi=acos(-1.0),eps=1e-4;8
struct
complex
11 complex operator+(const complex &x)const
12 complex operator-(const complex &x)const
13 complex operator*(const complex &x)const
14 complex &operator*=(const complex &x)
15 }a[maxn],b[maxn],c[maxn],d[maxn],e[maxn],f[maxn],i[maxn];//
d是a每項取平方,e是b每項取平方,f是b每項取立方,i是偽單位元
16void fft(complex*,int,int
);17
char
s[maxn],t[maxn];
18int n,m,n=1,ans=0;19
intmain()
31 reverse(t,t+m);
32for(int i=0;i)
37 fft(a,n,1
);38 fft(b,n,1
);39 fft(d,n,1
);40 fft(e,n,1
);41 fft(f,n,1
);42 fft(i,n,1);//
woc,這麼多fft慢不慢啊
43for(int i=0;i)
48 fft(a,n,-1
);49 fft(d,n,-1
);50 fft(f,n,-1
);51
for(int i=0;i)
55for(int i=0;i+m<=n;i++)if(c[i+m-1].a;
56 printf("
%d\n
",ans);
57for(int i=0;i+m<=n;i++)if(c[i+m-1].a"
%d\n
",i);
58return0;
59}60void fft(complex *a,int n,int
tp)while(j
67if(i
69for(int k=2;k<=n;k<<=1)78
}79}80
if(tp<0)for(int i=0;in;81}
82/*
83把t反轉,把s和t變成多項式a和b,令
84c[i+m-1]=sum
85顯然只有c是0的位置兩串才會匹配,展開得
86c[i+m-1]=sum
87前兩項是卷積形式,第三項乘上乙個偽單位元也是卷積形式,fft加速即可
88*/
ps:其實對$i$跑的那個dft完全沒必要,手動逐項賦成1就行了,然後發現$f$卷完了$i$根本沒有什麼變化,所以直接對$f$做一下dft再idft回去即可,把$i$寫進去只是為了理解式子方便......
upd:腦殘了……那個ps是錯的,忽視掉吧……
你,究竟是不是你?
聽得到的萬維鋼精英日課,有感 我們先設想一下,若干年後,我們快要死去的時候,利用科技,把你的腦袋全部複製上傳了,來實現永生。50年後,上傳意識的技術已經完美實現。有一家公司就專門提供上傳意識的商業服務。那時候的你大概七八十歲,是個億萬富翁,完全有能力購買這項服務。三年前,你的妻子就把意識上傳到乙個仿...
你是不是得了拖延症?
前段時間做年終總結,發現自己過去一年渾渾噩噩,毫無計畫都是被逼著往前走,後知後覺,做事瞻前顧後,唯唯諾諾,害怕接受新事物,害怕挑戰,只願意活在自己舒服的圈子裡,不願意去突破,做事不是找方法,而是充滿抱怨,原來我是患上了拖延症了。最近就找些拖延症方面的資料,做一些總結,希望自己自信,改掉壞毛病。拖延症...
你是不是太浮躁了?
你是不是太浮躁了?在這個浮躁的年代,很多程式設計師都極其浮躁,沒法靜下心來。小趙身上也有我的影子,我剛畢業那幾年也是像追星一樣追技術,每個技術都是淺嘗輒止,幸好後來幡然悔悟。其實學習熱門技術沒什麼錯,計算機發展這麼快,你不了解很快就落伍。關鍵是要有選擇性,得有自己的方向,能夠耐得住寂寞,經得住 在自...