2019牛客第三场 F Planting Trees

上次cf做了一道二维单调队列,于是在这里也枚举右下角的点用二维单调队列,结果好像不行,,,

最后题解是直接枚举上下边界,然后从左到右单调队列扫过去记录,记录当前右边界下最远的左边界可以在哪

中间超时,加了很多优化,结果是最后在mi[i]赋初值的地方出了问题,以前一直做1e5的题目,用maxl作最大值,结果这里数值大小是1e5,maxl只有500。。。

#include
#define maxl 510
using namespace std;

namespace fastIO 
{
    #define BUF_SIZE 100000
    bool IOerror = 0;
    inline char nc() 
    {
        static char buf[BUF_SIZE];
        static char *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
        if(p1 == pend) 
        {
            p1 = buf;
            pend = buf + fread(buf, 1, BUF_SIZE, stdin);
            if(pend == p1) 
            {
                IOerror = 1;
                return -1;
            }
        }
        return *p1++;
    }
    inline bool blank(char ch) {
        return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
    }
    inline int rd(int &x) 
    {
        char ch;
        while(blank(ch = nc()));
        if(IOerror) return -1;
        for(x=ch-'0';(ch=nc())>='0' && ch<='9';x=x*10+ch-'0');
        return 1;
    }
    #undef BUF_SIZE
};
using namespace fastIO;

int n,m,ans;
int a[maxl][maxl];
int mi[maxl],mx[maxl];
int miq[maxl],mxq[maxl];

inline void prework()
{
	//scanf("%d%d",&n,&m);
	rd(n);rd(m);
	for(register int i=1;i<=n;++i)
		for(register int j=1;j<=n;++j)
			//scanf("%d",&a[i][j]);
			rd(a[i][j]);
}

inline int max(int a,int b)
{
	if(a>b) return a;
	else return b;
}
inline int min(int a,int b)
{
	if(a=mx[mxq[mxt]])
					--mxt;
				mxq[++mxt]=i;
				while(mih<=mit && mxh<=mxt && mx[mxq[mxh]]-mi[miq[mih]]>m)
				{
					l=min(mxq[mxh]+1,miq[mih]+1);
					while(mih<=mit && miq[mih]

 

你可能感兴趣的:(单调队列)