神奇做法,神奇算法
#include<cstdio> #include<cstdlib> #include<stack> #include<algorithm> using namespace std; int n,m; const int N=303; int d[N][N],mn[N],f[N]; int ans[N*N]; stack <int > s; void calc() { int sum; for(int i=1;i<=n;i++) { sum=1,f[i]=1;//初始化 while(!s.empty() && mn[s.top() ] > mn[i] )//然后从这一行向上扩展 { f[i]+=f[s.top() ]; ans[mn[s.top() ] ]+=f[s.top() ]*sum; sum+=f[s.top() ]; s.pop() ; } s.push(i); } sum=1; while(!s.empty() ) { ans[mn[s.top() ] ]+=f[s.top() ]*sum; sum+=f[s.top() ]; s.pop() ; } } int main() { //input scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&d[i][j]); //work for(int i=1;i<=m;i++)//枚举左端点 { for(int j=1;j<=n;j++) mn[j]=d[j][i]; calc(); for(int j=i+1;j<=m;j++)//枚举右端点 { for(int k=1;k<=n;k++) mn[k]=min(mn[k],d[k][j]);//一行一行的得到mn值 calc();//求左右端点之间,以各行结尾的矩形数 } } //output int mx=n*m; for(int i=1;i<=mx;i++) printf("%d\n",ans[i]); return 0; }