对于每一行,用一个2^12个01来表示,其中这一行就是其中所有为1的点所代表的行(i二进制中包含的行)的max的min,然后就可以支持取max和min了,查询只需要枚举答案即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 bitset<5005>f[N]; 5 int n,m,q,p,x,y,a[21][N],id[N][21]; 6 bool cmp(int x,int y){ 7 return a[x][p]>a[y][p]; 8 } 9 int main(){ 10 scanf("%d%d%d",&m,&n,&q); 11 for(int i=1;i<=n;i++) 12 for(int j=1;j<=m;j++)scanf("%d",&a[i][j]); 13 for(int i=1;i<=m;i++){ 14 for(int j=1;j<=n;j++)id[i][j]=j; 15 p=i; 16 sort(id[i]+1,id[i]+n+1,cmp); 17 } 18 for(int i=1;i<=n;i++) 19 for(int j=0;j<(1<<n);j++) 20 if (j&(1<<i-1))f[i][j]=1; 21 for(int i=1;i<=q;i++){ 22 scanf("%d%d%d",&p,&x,&y); 23 if (p==1)f[++n]=(f[x]|f[y]); 24 if (p==2)f[++n]=(f[x]&f[y]); 25 if (p==3){ 26 int t=0; 27 for(int j=1;j<=n;j++){ 28 t|=(1<<id[y][j]-1); 29 if (f[x][t]){ 30 printf("%d ",a[id[y][j]][y]); 31 break; 32 } 33 } 34 } 35 } 36 }