#include<bits/stdc++.h> #define FILE "read" #define MAXN 100100 using namespace std; int n,m,Q,cnt,f[MAXN*20],A[15][MAXN]; struct node{ int sum,L,R,l[15],r[15]; node(){sum=0;} }tr[MAXN<<2]; inline int read(){ int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } int find(int x){return f[x]==x?x:f[x]=find(f[x]);} inline node operator +(node a,node b){ if(!a.sum) return b; if(!b.sum) return a; node c; c.sum=a.sum+b.sum; c.L=a.L; c.R=b.R; for(int i=1;i<=n;++i){ f[a.l[i]]=a.l[i]; f[a.r[i]]=a.r[i]; f[b.l[i]]=b.l[i]; f[b.r[i]]=b.r[i]; } for(int i=1;i<=n;++i)if(A[i][a.R]==A[i][b.L]){ int p=find(a.r[i]),q=find(b.l[i]); if(p==q) continue; c.sum--; f[p]=q; } for(int i=1;i<=n;++i){ c.l[i]=find(a.l[i]); c.r[i]=find(b.r[i]); } return c; } void build(int p,int l,int r){ if(l==r){ for(int i=1;i<=n;++i){ if(A[i][l]==A[i-1][l]) tr[p].l[i]=tr[p].r[i]=tr[p].l[i-1]; else tr[p].l[i]=tr[p].r[i]=++cnt,tr[p].sum++; } tr[p].L=l; tr[p].R=r; return; } int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); tr[p]=tr[p<<1]+tr[p<<1|1]; } node query(int p,int l,int r,int x,int y){ if(x<=l&&y>=r) return tr[p]; int mid=(l+r)>>1; node ret; if(x<=mid) ret=ret+query(p<<1,l,mid,x,y); if(y>mid) ret=ret+query(p<<1|1,mid+1,r,x,y); return ret; } int main(){ n=read(); m=read(); Q=read(); for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)A[i][j]=read(); build(1,1,m); for(int i=1;i<=Q;++i){ int l=read(),r=read(); printf("%d\n",query(1,1,m,l,r).sum); } return 0; }
|