被FFT的空间卡了半天 后来发现根本不用开那么大...

首先可以把包含舰艇的那个小矩形找出来 将它一行一行连接成一个串T 其中舰艇位置为1其他位置为0 将大矩形也连成串S 其中礁石为1其他为0

两个串匹配起来如果某一位两个串是1和1 则礁石与舰艇会在同一位置不可能到达 那么这个匹配所对应的图中的位置就不成立

因为要确定每个位置可以想到将T翻转后做FFT后每一位(每一位代表了一个小矩形的匹配情况)上结果是0就可以匹配上 为1不成立 选出为0的 做一遍BFS 求出可以到达的位置

可以发现可行的状态里面会有重复的空地 所以再做一次FFT T串为小矩形的正序串 S串为BFS后的可行装状态串 之后对结果的数组中实数个数计数就是答案咧

#include<bits/stdc++.h>
#define bug(x) cout<<(#x)<<" "<<(x)<<endl
#define ll long long
#define mod 1000000007
#define inf 2e9
#define PI acos(-1.0)
#define pii pair<int,int>
#define fi first
#define se second
#define mk make_pair
using namespace std;
const int N=1e6+5
const int MXN=7e2+5;
struct cp {
double x,y;
cp(double _x=0,double _y=0) { x=_x,y=_y;}
}A[N],B[N];
cp operator + (cp x,cp y){cp z;z.x=x.x+y.x;z.y=x.y+y.y;return z;}
cp operator - (cp x,cp y){cp z;z.x=x.x-y.x;z.y=x.y-y.y;return z;}
cp operator * (cp x,cp y){cp z;z.x=x.x*y.x-x.y*y.y;z.y=x.y*y.x+x.x*y.y;return z;} int ans,up=inf,dn,lf=inf,rt,W,H,all,k,len,M,n,m,r[N],T[N];
queue<pii >q;
char a[MXN][MXN];
bool vis[N],v[N];
void init(){
for(int i=0;i<n;i++) for(int j=0;j<m;j++){
if(a[i][j]=='#') B[i*m+j]=cp(1,0);
else if(a[i][j]=='o'){
up=min(up,i),dn=max(dn,i);
lf=min(lf,j),rt=max(rt,j);
}
}
for(int i=up;i<=dn;i++) for(int j=lf;j<=rt;j++) if(a[i][j]=='o')T[(i-up)*m+j-lf]=1;
W=rt-lf+1,H=dn-up+1,len=(H-1)*m+W;
}
void FFT(cp *x,int f){
for(int i=0;i<M;i++) if(r[i]>i) swap(x[r[i]],x[i]);
for(int i=1;i<M;i<<=1){
cp wn(cos(PI/i),f*sin(PI/i));
for(int j=0;j<M;j+=i<<1){
cp w=1;
for(int k=0;k<i;k++,w=w*wn){
cp a=x[j+k],b=w*x[j+k+i];
x[j+k]=a+b,x[j+k+i]=a-b;
}
}
}
if(f==-1) for(int i=0;i<M;i++) x[i].x/=M;
}
void work(){
q.push(mk(dn,rt));
while(!q.empty()){
int x=q.front().fi,y=q.front().se;q.pop();
if(x<0||x>=n||y<0||y>=m) continue;
int z=x*m+y;
if(!v[z]||vis[z]) continue;
vis[z]=1;
q.push(mk(x+1,y)),q.push(mk(x-1,y)),q.push(mk(x,y-1)),q.push(mk(x,y+1));
}
}
int main(){
#ifdef Devil_Gary
freopen("in.txt","r",stdin);
#endif /* freopen("sailing.in","r",stdin);
freopen("sailing.out","w",stdout);*/
cin>>n>>m,all=n*m;
for(int i=0;i<n;i++) scanf("%s",a[i]);
init();
for(M=1;M<=all;M<<=1,k++);
for(int i=1;i<M;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(k-1));
for(int i=0;i<len;i++) if(T[i]) A[len-i-1]=1;
FFT(A,1),FFT(B,1);
for(int i=0;i<M;i++) A[i]=A[i]*B[i];
FFT(A,-1);
for(int i=H-1;i<n;i++) for(int j=W-1;j<m;j++)
if(A[i*m+j].x<0.5) v[i*m+j]=1;
work();
for(int i=0;i<M;i++) A[i]=T[i];
for(int i=0;i<M;i++) B[i]=vis[i];
FFT(A,1),FFT(B,1);
for(int i=0;i<M;i++) A[i]=A[i]*B[i];
FFT(A,-1);
for(int i=0;i<M;i++) if(A[i].x>0.5) ans++;
return printf("%d\n",ans),0;
}

BZOJ5217: [Lydsy2017省队十连测]航海舰队 FFT的更多相关文章

  1. BZOJ5217:[Lydsy2017省队十连测]航海舰队——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5217 Byteasar 组建了一支舰队!他们现在正在海洋上航行着.海洋可以抽象成一张n×m 的网格 ...

  2. bzoj 5217: [Lydsy2017省队十连测]航海舰队

    Description Byteasar 组建了一支舰队!他们现在正在海洋上航行着.海洋可以抽象成一张n×m 的网格图,其中有些位置是" .",表示这一格是海水,可以通过:有些位置 ...

  3. Lydsy2017省队十连测

    5215: [Lydsy2017省队十连测]商店购物 可能FFT学傻了,第一反应是前面300*300背包,后面FFT... 实际上前面背包,后面组合数即可.只是这是一道卡常题,需要注意常数.. //A ...

  4. bzoj 5216 [Lydsy2017省队十连测]公路建设 线段树维护 最小生成树

    [Lydsy2017省队十连测]公路建设 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 93  Solved: 53[Submit][Status][ ...

  5. bzoj 5216: [Lydsy2017省队十连测]公路建设

    5216: [Lydsy2017省队十连测]公路建设 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 66  Solved: 37[Submit][St ...

  6. 2018.09.26 bzoj5218: [Lydsy2017省队十连测]友好城市(回滚莫队)

    传送门 比较简单的一道回滚莫队吧. 每次询问用bitset优化kosaraju统计答案. 就是有点难调. 然后向dzyo学长学习了回滚莫队的一种简洁的实现方式,就是直接建立一个sqrt(m)∗sqrt ...

  7. bzoj 5218: [Lydsy2017省队十连测]友好城市

    题意: 这题显然直接tarjan是做不了的. 这里安利另一个求SCC的算法Kosaraju,学习的话可以见这篇博客 于是结合莫队,我们有了个暴力. 发现主要瓶颈是dfs过程中找最小的未经过的点,我们用 ...

  8. 【BZOJ 5222】[Lydsy2017省队十连测]怪题

    题目大意: 传送门 给一个长度为$n(n<=200)$的数列$h$,再给$m$个可以无限使用的操作,第$i$个操作为给长度为花费$c_i$的价值给长度为$l_i$的数列子序列+1或-1,求将数列 ...

  9. 2018.09.26 bzoj5221: [Lydsy2017省队十连测]偏题(数学推导+矩阵快速幂)

    传送门 由于没有考虑n<=1的情况T了很久啊. 这题很有意思啊. 考试的时候根本不会,骗了30分走人. 实际上变一个形就可以了. 推导过程有点繁杂. 直接粘题解上的请谅解. 不得不说这个推导很妙 ...

随机推荐

  1. Linux内核跟踪之trace框架分析【转】

    转自:http://blog.chinaunix.net/uid-20543183-id-1930846.html   ---------------------------------------- ...

  2. Mysql转换成SqlServer数据库,以及SqlServer转换成Mysql数据库

    Windows XP sp2 MS SQL Server 2OOO sp1 MySql 5.0.41 1:MSSQLServer数据库导入到MySql数据库 步骤: 1.安装mysql数据库的ODBC ...

  3. 二、springboot配置

    一.启动类 在包根目录下添加启动类,必须包含main方法,再添加Spring Boot启动方法: SpringApplication.run(SampleController.class, args) ...

  4. 20 Organizing Go code 组织go代码

    Organizing Go code 16 August 2012 Introduction Go code is organized differently to that of other lan ...

  5. VBA笔记-参考教程

    参考教程1: http://www.cnblogs.com/wuzhiblog/tag/VBA/ 1. VBA中字符换行 VBA中字符换行显示需要使用换行符来完成.下面是常用的换行符          ...

  6. windows下同时安装python2和python3

    之前学习的时候使用2.7比较多. 想练习3.7的时候,两个版本兼容的问题,苦恼了几天. 查了一下资料,发现了一个很好的方法.记录一下,也做一个分享. 本篇内容主要讲一下,在同一台电脑上如何同时安装Py ...

  7. No.9 selenium学习之路之CSS定位

    CSS定位方式: 元素中间加“.”表示是class 1.通过ID定位 driver.find_element_by_css_selector("#ID值") 2.通过class定位 ...

  8. 一步步教你编写不可维护的 PHP 代码

    译者注:这是一篇很棒文章,使用有趣的叙述方式,从反面讲解了作为一个优秀的 PHP 工程师,有哪些事情是你不能做的.请注意哦,此篇文章罗列的行为,都是你要尽量避免的. 随着失业率越来越高,很多人意识到保 ...

  9. Ajax请求中的async:false/true

    Ajax请求中的async:false/trueasync. 默认是 true,即为异步方式,$.ajax执行后,会继续执行ajax后面的脚本,直到服务器端返回数据后,触发$.ajax里的succes ...

  10. element-ui 2.7.2版本使用 表格展开行 功能遇到的奇葩问题?

    在使用 element-ui 2.7.2版本的时候报下面的错误: [Vue warn]: Error in callback for watcher "data": "E ...