标签:name cst 最大值 stream printf int ring turn 就是
我发现我是越来越傻叉了。。
本机运行死活过不去数据,拍了贼久就是不出错,一怒之下直接交居然A了。。。
我的做法是先把当前行j-k+1~j列的最值用单调队列搞出来
然后再搞一次行的单调队列的最值
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; LL a[1100][1100]; LL mx[1100][1100],mn[1100][1100];//lmx[i][j]表示第i行第j-k+1~j列 的最大值 struct node { int p;LL d; }mxq[1100],mnq[1100];int mxl,mxr,mnl,mnr; int main() { freopen("data.in","r",stdin); freopen("1.out","w",stdout); int n,m,k; scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%lld",&a[i][j]); for(int i=1;i<=n;i++) { mxl=1,mxr=0,mnl=1,mnr=0; for(int j=1;j<=m;j++) { while(mxl<=mxr&&mxq[mxl].p+k-1<j)mxl++; while(mxl<=mxr&&mxq[mxr].d<=a[i][j])mxr--; mxr++; mxq[mxr].p=j, mxq[mxr].d=a[i][j]; mx[i][j]=mxq[mxl].d; while(mnl<=mnr&&mnq[mnl].p+k-1<j)mnl++; while(mnl<=mnr&&mnq[mnr].d>=a[i][j])mnr--; mnr++; mnq[mnr].p=j, mnq[mnr].d=a[i][j]; mn[i][j]=mnq[mnl].d; } } LL ans=(1LL<<61); for(int j=k;j<=m;j++) { mxl=1,mxr=0,mnl=1,mnr=0; for(int i=1;i<=n;i++) { while(mxl<=mxr&&mxq[mxl].p+k-1<i)mxl++; while(mxl<=mxr&&mxq[mxr].d<=mx[i][j])mxr--; mxr++; mxq[mxr].p=i, mxq[mxr].d=mx[i][j]; while(mnl<=mnr&&mnq[mnl].p+k-1<i)mnl++; while(mnl<=mnr&&mnq[mnr].d>=mn[i][j])mnr--; mnr++; mnq[mnr].p=i, mnq[mnr].d=mn[i][j]; if(i-k+1>0)ans=min(ans,mxq[mxl].d-mnq[mnl].d); } } printf("%lld\n",ans); return 0; }
标签:name cst 最大值 stream printf int ring turn 就是
原文地址:https://www.cnblogs.com/AKCqhzdy/p/8902018.html