【ICPC2019银川站】K - Largest Common S
原题:
题意:
给你两个n*m的矩阵,在每个矩阵中,元素的值都是1-n*m且互不相同
问你这两个矩阵的最大公共子矩阵有多大
首先可以想到由于每个值在一个矩阵只出现一次,因此两个矩阵之间建立了一个映射关系
接着考虑在和子矩阵有关的方面,这个关系有什么性质
可以发现,某个相等子矩阵中每一个元素的偏移量一定相同
因此可以计算左边矩阵每个值到右边矩阵的偏移量
为了方便计算,给每一种偏移量分配一个颜色
问题转化为,给一个颜色矩阵,求一个最大的单色子矩阵
对于有两种颜色的矩阵,可以用单调队列来求,那么对于多种颜色的矩阵呢
可以发现,在某一行的单调队列处理的过程种
如果某个元素和上一个元素颜色不一样,那么就可以直接把队列清空
如果和上一个元素颜色一样,就按照常规单调队列处理
这本质上是利用了不同颜色之间绝对排斥的性质
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 struct nds{int x,y,u,v;}c[1100000]; 6 int n,m,a[1100][1100],b[1100][1100]; 7 int bx[1100000],by[1100000]; 8 int d[1100][1100],dt=0; 9 //nds q[1100][1100]; 10 //int hd[1100]; 11 nds q[1100]; 12 int hd=0; 13 int f[1100][1100]; 14 int od[1100000],ot=0; 15 int ans=0; 16 int id(int x,int y){ return (x-1)*m+y-1;} 17 void otd(){ 18 for(int i=1;i<=n;++i){ 19 for(int j=1;j<=m;++j) printf("%d ",d[i][j]); 20 printf("\n"); 21 } 22 } 23 void sv(int x){ 24 hd=0; 25 q[0].x=0,q[0].y=0; 26 for(int i=1;i<=m;++i){ 27 if(d[x][i]!=d[x][i-1]){ 28 while(hd>0){ 29 ans=max(ans,(i-q[hd-1].x-1)*q[hd].y); 30 hd--; 31 } 32 q[0].x=i-1; //attention 33 } 34 else{ 35 while(hd>0 && q[hd].y>=f[x][i]){ 36 ans=max(ans,(i-q[hd-1].x-1)*q[hd].y); 37 hd--; 38 } 39 } 40 q[++hd]=(nds){i,f[x][i],0,0}; 41 } 42 while(hd>0){ 43 ans=max(ans,(m-q[hd-1].x)*q[hd].y); 44 hd--; 45 } 46 } 47 bool cmp(nds x,nds y){ 48 return x.x==y.x ? x.y<y.y : x.x<y.x; 49 } 50 int main(){ 51 scanf("%d%d",&n,&m); 52 for(int i=1;i<=n;++i)for(int j=1;j<=m;++j) 53 scanf("%d",&a[i][j]); 54 for(int i=1;i<=n;++i)for(int j=1;j<=m;++j){ 55 scanf("%d",&b[i][j]); 56 bx[b[i][j]]=i; 57 by[b[i][j]]=j; 58 } 59 for(int i=1;i<=n;++i)for(int j=1;j<=m;++j) 60 c[id(i,j)+1]=(nds){bx[a[i][j]]-i,by[a[i][j]]-j,i,j}; 61 sort(c+1,c+n*m+1,cmp); 62 c[0].x=-1,c[0].y=-1; 63 for(int i=1;i<=n*m;++i){ 64 if(c[i].x!=c[i-1].x || c[i].y!=c[i-1].y) ++dt; 65 d[c[i].u][c[i].v]=dt; 66 } 67 for(int i=1;i<=n;++i)for(int j=1;j<=n;++j){ 68 if(d[i][j]==d[i-1][j]) f[i][j]=f[i-1][j]+1; 69 else f[i][j]=1; 70 } 71 for(int i=1;i<=n;++i) sv(i); 72 printf("%d\n",ans); 73 return 0; 74 }