洛谷P2216 [HAOI2007]理想的正方形
吐槽:重装系统重装了chrome它就把我博客园的账号和密码给忘了。然后我还不知道用哪个邮箱注册的,找了一上午才找回来。
题意概述:选一个子矩阵使最大值-最小值尽量小。
先考虑n^4暴力……很好写然后T到天上去。然后考虑对每行建st表……还是T到天上去。最后考虑建个二维st表……就好了。
#include<cstring> #include<iostream> #include<cctype> #include<cstdio> #include<algorithm> using namespace std; int read() { int X=0;char ch=0;bool flag=0; for(;!isdigit(ch);ch=getchar()) if(ch=='-') flag=1; for(;isdigit(ch);ch=getchar()) X=(X<<3)+(X<<1)+ch-'0'; return (flag ? -X : X); } void write(int x) { if(x>9) write(x/10); putchar(x%10+'0'); } int a,b,n,s[1001][1001][15],t[1001][1001][15],ans=2147483644,log[1001]; int mx(int a,int b,int c,int d) {if(b>a)a=b;if(c>a)a=c;if(d>a)a=d;return a;} int mn(int a,int b,int c,int d) {if(b<a)a=b;if(c<a)a=c;if(d<a)a=d;return a;} void st() { int lim=log[min(a,b)]; for(int k=1;k<=lim;k++) for(int i=1;i<=a-(1<<k)+1;i++) for(int j=1;j<=b-(1<<k)+1;j++) s[i][j][k]=mx(s[i][j][k-1],s[i][j+(1<<k-1)][k-1], s[i+(1<<k-1)][j][k-1],s[i+(1<<k-1)][j+(1<<k-1)][k-1]), t[i][j][k]=mn(t[i][j][k-1],t[i][j+(1<<k-1)][k-1], t[i+(1<<k-1)][j][k-1],t[i+(1<<k-1)][j+(1<<k-1)][k-1]); } int qu(int x,int y,int x1,int y1) { int k=log[n],xx=0,mm=2e9; xx=mx(s[x][y][k],s[x][y1-(1<<k)+1][k], s[x1-(1<<k)+1][y][k],s[x1-(1<<k)+1][y1-(1<<k)+1][k]); mm=mn(t[x][y][k],t[x][y1-(1<<k)+1][k], t[x1-(1<<k)+1][y][k],t[x1-(1<<k)+1][y1-(1<<k)+1][k]); return xx-mm; } int main() { a=read(),b=read(),n=read(); log[0]=-1;for(int i=1;i<=a+b;i++) log[i]=log[i>>1]+1; for(int i=1;i<=a;i++) for(int j=1;j<=b;j++) s[i][j][0]=t[i][j][0]=read(); st(); for(int i=1;i<=a-n+1;i++) for(int j=1;j<=b-n+1;j++) ans=min(ans,qu(i,j,i+n-1,j+n-1)); write(ans); }
忘开longlong,忘用逆元,忘删调试信息,瞬间爆炸