1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| #include<cstdio> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<cstring> #include<set> #include<map> #include<cmath> #include<iostream> #include<unordered_set> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define Inf 0x3f3f3f3f
using namespace std; typedef long long LL; typedef pair<int,int> P; typedef pair<P,int> PP; const int MAXX=1000005; const double eps=0.0000001;
int n,m,p[MAXX];
void lgetpmt(const vector<vector<char> >& a,int k){ for(int i=1,j=0;i<m;++i){ while(j>0&&a[k][i+1]!=a[k][j+1]) j=p[j]; if(a[k][i+1]==a[k][j+1]) ++j; p[i+1]=j; } } void tgetpmt(const vector<vector<char> >& a,int k){ for(int i=1,j=0;i<n;++i){ while(j>0&&a[i+1][k]!=a[j+1][k]) j=p[j]; if(a[i+1][k]==a[j+1][k]) ++j; p[i+1]=j; } }
inline void solve_it(){ scanf("%d%d",&n,&m); vector<vector<char> > a(n+2,vector<char>(m+2)); vector<vector<int> > c(n+2,vector<int>(m+2)); for(int i=1;i<=n;++i){ getchar(); for(int j=1;j<=m;++j) scanf("%c",&a[i][j]); } for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) scanf("%d",&c[i][j]); map<int,int> left,top; int l=m,t=n; for(int i=1;i<=n;++i){ lgetpmt(a,i); int jj=p[m]; while(jj!=0){ ++left[m-jj]; if(left[m-jj]==n) l=min(l,m-jj); jj=p[jj]; } } for(int i=1;i<=m;++i){ tgetpmt(a,i); int jj=p[n]; while(jj!=0){ ++top[n-jj]; if(top[n-jj]==m) t=min(t,n-jj); jj=p[jj]; } }
priority_queue<P> pq; vector<vector<int> > topmax(n+2,vector<int>(m+2)); for(int j=1;j<=m;++j){ while(!pq.empty()) pq.pop(); for(int i=1;i<=t;++i) pq.emplace(c[i][j],i); topmax[t][j]=pq.top().first; for(int i=t+1;i<=n;++i){ pq.emplace(c[i][j],i); while(pq.top().second<=i-t) pq.pop(); topmax[i][j]=pq.top().first; } } int ans=Inf; for(int i=t;i<=n;++i){ while(!pq.empty()) pq.pop(); for(int j=1;j<=l;++j) pq.emplace(topmax[i][j],j); ans=min(ans,pq.top().first); for(int j=l+1;j<=m;++j){ pq.emplace(topmax[i][j],j); while(pq.top().second<=j-l) pq.pop(); ans=min(ans,pq.top().first); } }
printf("%lld\n",((LL)ans)*((LL)(l+1))*((LL)(t+1))); }
signed main(){
solve_it(); return 0; }
|