如果你做過bzoj5217:[lydsy2017省隊十連測]航海艦隊的話,那麼恭喜你,這道題就是大水題。
如果你做過bzoj4259:殘缺的字串的話,那麼基本的字串匹配fft也是能想到的。
如果沒做過的話,很抱歉,沒有一定的套路的話這道題很難想(而對於我這樣的蒟蒻來說就是沒法想。)
將行走路線看做乙個地圖b,走過的路為1,沒走的為0.
於是可以變成這張地圖可以與原地圖a匹配多少次(匹配成功在於兩張圖的1不能重疊。)
按照bzoj5217的套路,將二維壓成一維,就變成了對於乙個下標為p的點,不滿足a[p+i]=1且b[i]=1。
於是有f[i]=sigma(a[i+j]*b[j])=0,將a陣列顛倒得f[i]=sigma(a[n*m-i-j]*b[j])=0是卷積,可以fft運算。
最後統計f[i]=0的個數即可。
#include#include#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
typedef
double
dl;const dl pi=acos(-1.0
);const dl eps=0.5
;const
int m=1505
;const
int n=m*m*8
;const
int k=5e6+5
;struct
complex
complex
operator +(const complex &b)const
complex
operator -(const complex &b)const
complex
operator *(const complex &b)const
};void fft(complex a,int n,int
on)
if(jk;
}for(int i=2;i<=n;i<<=1
) }
}if(on==-1
)
for(int i=0;in;
}bool tmp[m*2+10][m*2+10
];int
n,m,k;
char
mp[m][m],s[k];
complex a[n],b[n];
intmain()
for(int i=x1;i<=x2;i++)
for(int j=y1;j<=y2;j++)
if(tmp[i][j])b[(i-x1)*m+j-y1]=complex(1,0
);
int len=1
;
while(len1
; fft(a,len,
1);fft(b,len,1
);
for(int i=0;ib[i];
fft(a,len,-1
);
int ans=0
;
for(int i=1;i<=n-(x2-x1);i++)
for(int j=1;j<=m-(y2-y1);j++)
if(a[n*m-(i-1)*m-j].x;
printf(
"%d\n
",ans);
return0;
}
Loj10166 數字遊戲2
題目描述 由於科協裡最近真的很流行數字遊戲,某人又命名了一種取模數,這種數字必須滿足各位數字之和 modn 為 000。現在大家又要玩遊戲了,指定乙個整數閉區間 a,b a,b a,b 問這個區間內有多少個取模數。列舉每一位,記錄每一次列舉 n的餘數,當列舉完時,如果餘數是0,就 1,否則 0.in...
Loj10166 數字遊戲2
題目描述 由於科協裡最近真的很流行數字遊戲,某人又命名了一種取模數,這種數字必須滿足各位數字之和 modn 為 000。現在大家又要玩遊戲了,指定乙個整數閉區間 a,b a,b a,b 問這個區間內有多少個取模數。列舉每一位,記錄每一次列舉 n的餘數,當列舉完時,如果餘數是0,就 1,否則 0.in...
LOJ 6278 數列分塊入門 2
題意 給出乙個長為 n 的數列,以及 n個操作,操作涉及區間加法,詢問區間內小於某個值 x的元素個數。思路 這裡有兩種操作,一種是區間加法,這在上一部落格已經介紹過了,不會的戳這裡,還有一種是區間查詢,因為每次查詢的數字都是不一樣的,所以要想時間最優化,必須要排序,因為排序後的查詢操作可以達到log...