A \ (n \ times m \) the matrix, all initial state \ (0 \) .
If two adjacent elements (four communication) are equal, we say that they are in communication, and the relationship may be transferred.
There \ (Q \) operations, each specifying a location \ ((x_i, y_i) \ ) replace it with \ (C_i \) .
How many blocks each communication request after the matrix operation there.
\(q \leq 2\times 10^6\), \(n,m \leq 300\)
Solution
With deleted disjoint-set problem can be off-line, so positive with each doing a backwards, then the answer will be able to make the difference
Consider the process of being made, the beginning is a piece of \ (0 \) of the plate board
Every time we create a new node, and then attempt to merge it with the surrounding nodes, the number of merger set to \ (t \) , then this time contribution to the answers (that is, the operation of how many new communication block) is \ (1-t \)
Similarly, the contribution with a negative sign reverse operation on it
Finally, when the output of the answer, the contribution of the array and to seek prefix
#include <bits/stdc++.h>
using namespace std;
const int N = 305, M = 2000005;
int a[N][N],n,m,q,ind,num,f[M*2],ans[M],id[N][N];
struct query {
int x,y,b,c;
} s[M];
int find(int x) {return (x==f[x])?x:f[x]=find(f[x]);}
void merge(int x,int y) {if((x=find(x))-(y=find(y))) f[x]=y,--num;}
void solve(int x,int y) {
if(a[x][y]==a[x-1][y]) merge(id[x][y],id[x-1][y]);
if(a[x][y]==a[x+1][y]) merge(id[x][y],id[x+1][y]);
if(a[x][y]==a[x][y-1]) merge(id[x][y],id[x][y-1]);
if(a[x][y]==a[x][y+1]) merge(id[x][y],id[x][y+1]);
}
signed main() {
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=q;i++) {
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
s[i]={x,y,a[x][y],c};
a[x][y]=c;
}
memset(a,0xff,sizeof a);
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=0;
for(int i=1;i<=q;i++) {
if(s[i].b!=s[i].c) {
int x=s[i].x,y=s[i].y,b=s[i].b,c=s[i].c;
num=1;
a[x][y]=c;
id[x][y]=++ind;
f[ind]=ind;
solve(x,y);
ans[i]+=num;
}
}
ind=0;
memset(f,0,sizeof f);
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) {
id[i][j]=++ind;
f[ind]=ind;
}
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) solve(i,j);
for(int i=q;i>=1;--i) {
if(s[i].b!=s[i].c) {
int x=s[i].x,y=s[i].y,b=s[i].c,c=s[i].b;
num=1;
a[x][y]=c;
id[x][y]=++ind;
f[ind]=ind;
solve(x,y);
ans[i]-=num;
}
}
ans[0]=1;
for(int i=1;i<=q;i++) ans[i]+=ans[i-1];
for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
}