bzoj 1047 理想的正方形
2015-11-16 10:38
176 查看
利用单调队列维护以i,j为右下角的正方形的两个极值。把w大成h了。
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #define md #define ll long long #define inf (int) 1e9 #define eps 1e-8 #define N 1010 using namespace std; int a ,qmx ,qmn ; struct yts { int dt,pos;} q1 ,q2 ; int main() { int A,B,n; scanf("%d%d%d",&A,&B,&n); for (int i=1;i<=A;i++) for (int j=1;j<=B;j++) scanf("%d",&a[i][j]); for (int j=1;j<=B;j++) { int h=1,w=0; for (int i=1;i<=A;i++) { while (h<=w&&q1[h].pos<=i-n) h++; while (h<=w&&q1[w].dt<=a[i][j]) w--; q1[++w].pos=i; q1[w].dt=a[i][j]; qmx[i][j]=q1[h].dt; } h=1,w=0; for (int i=1;i<=A;i++) { while (h<=w&&q2[h].pos<=i-n) h++; while (h<=w&&q2[w].dt>=a[i][j]) w--; q2[++w].pos=i; q2[w].dt=a[i][j]; qmn[i][j]=q2[h].dt; } } int ans=inf; for (int i=n;i<=A;i++) { int h1=1,w1=0,h2=1,w2=0; for (int j=1;j<=B;j++) { while (h1<=w1&&q1[h1].pos<=j-n) h1++; while (h1<=w1&&q1[w1].dt<=qmx[i][j]) w1--; q1[++w1].pos=j; q1[w1].dt=qmx[i][j]; while (h2<=w2&&q2[h2].pos<=j-n) h2++; while (h2<=w2&&q2[w2].dt>=qmn[i][j]) w2--; q2[++w2].pos=j; q2[w2].dt=qmn[i][j]; if (j>=n) ans=min(ans,q1[h1].dt-q2[h2].dt); } } printf("%d\n",ans); return 0; }
相关文章推荐
- bzoj 3918 postman
- bzoj 3098 hash killer
- bzoj 1875 HH去散步
- bzoj 3679 数字之积
- bzoj 屯题计划 完结
- bzoj 3503 和谐矩阵
- bzoj 2242 计算器
- bzoj 2597 石头剪刀布
- bzoj 3532 lis
- bzoj 3130 费用流
- bzoj 1500 维修数列 bzoj 1507 editor
- bzoj 1251 序列终结者
- bzoj 4152 the camptin (dis[x][y]=min(|x.x-y.x|,|x.y-y.y|),求1,n最短路)
- bzoj 3029 守卫者的挑战
- bzoj 2118 墨墨的等式
- <android5.0>之曲线动画(Curved motion(曲线运动))
- 浅谈虚数i在电路分析中的作用
- 【数据库7】字段相关与联合结果集
- Jenkins入门系列之——02第二章 Jenkins安装与配置
- 简述类目的优缺点,如果覆盖了本类或者父类的方法 ,会出现什么问题