[ZJOI2009]对称的正方形 manacher+单调队列
快看,这里有个蒟蒻不会写单调队列!
弱者就是弱。啥思路没有,码力还不行。
显然的思路是考虑每一个中心点,求最大边长。发现每个点的限制挺难维护的。其实可以把限制拆开,拆成上下左右四个方向,最后求个min。
以向上的方向为例。我们想求向上能扩展的最大边长。从上往下扫,维护半径单调递增的单调队列,每次从队头弹掉半径过小的点,记录最后一个弹掉的队头。然后边长就很好求了。
然后我就写不出来了
#include
using namespace std;
typedef pair pii;
#define forg(i,x) for(int i=fir[x];i;i=nxt[i])
#define uu unsigned
#define scanf a1234=scanf
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define rint register int
int a1234;
char buf[1<<18],*bufs=buf,*buft=buf;
inline int gc(){
return bufs==buft&&(buft=(bufs=buf)+fread(buf,1,1<<18,stdin)),bufs==buft?-1:*bufs++;
}
inline void xxx(){for(;;);}
inline int rd(int l,int r){return rand()%(r-l+1)+l;}
const int mxn=2005;
int a[mxn][mxn],ra[mxn],r1[mxn][mxn],r2[mxn][mxn];
int n,m;
inline void man1(rint x){
//横向
rint md=-1,rp=-1;
for(rint i=1;i<=m;++i){
if(i
说几个比较重要的细节吧。
还是以向上的方向为例(work1),如果中心行是\(i\)行,上界是第\(x\)行 (上界一定是关键行,但是第i行可以是辅助行),边长就是\(i-x+1\) 分类讨论一下挺好推的
还有每次更新lim的时候其实应该特判关键行,但是不判也没事。