Codeforces1303 F Number of Components
Posted yspm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces1303 F Number of Components相关的知识,希望对你有一定的参考价值。
Description
题意:给一个全(0)矩阵,每次支持一个修改,修改不还原(这要是还原了不就成(A)题了)
然后询问每一次修改完了当前矩阵的连通块个数
每一个修改的值单调不降
修改次数 (leq 10^6)
Solution
这个是一道并查集题(感觉我原来从来没有写过任何并查集维护信息的题目)
具体就是我们对于每一个修改要考虑的是这个修改带来的贡献,就是和相邻颜色的对比
能合并的就合并一下,然后统计答案
这时,我们把这个题转化成了对每一种颜色考虑,然后看这个颜色的改变(最后开个桶就成了)
对于每种颜色,会有两种:添加一个颜色(正序处理),颜色被覆盖(逆序处理)
逆序的原因是被覆盖的时候原先有的这个连通块可能被整成多个连通块
(如果我们逆序处理覆盖,就等同于正序处理添加,贡献相减即可)
真是一道并查集应用的不错题目
Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k=='-') f=-1;
while(isdigit(k)) res=res*10+k-'0',k=getchar();
return res*f;
}
const int N=310,Q=2e6+10;
int fx[4]={0,-1,1,0},fy[4]={-1,0,0,1};
int n,m,q,maxx,ans[Q],fa[N*N],now[N][N];
struct query{int id,x,y;}; vector<query>q1[Q],q2[Q];
inline int num(int x,int y){return (x-1)*m+y;}
inline int rt(int x){return fa[x]==x?x:fa[x]=rt(fa[x]);}
inline bool in(int x,int y){return x>0&&x<=n&&y>0&&y<=m;}
inline void clear(int n){for(int i=1;i<=n;++i) fa[i]=i; return ;}
inline bool merge(int x,int y){x=rt(x),y=rt(y); if(x==y) return 0; return fa[x]=y,1;}
signed main()
{
n=read(); m=read(); q=read();
for(int i=1,x,y,c;i<=q;++i)
{
x=read(),y=read(),c=read(); maxx=c;
q2[now[x][y]].push_back((query){i,x,y});
q1[now[x][y]=c].push_back((query{i,x,y}));
}
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j) q2[now[i][j]].push_back((query){0,i,j});
}memset(now,-1,sizeof(now));
for(int i=0,sz,id,x,y;i<=maxx;++i)
{
sz=q1[i].size(); if(!sz) continue; clear(n*m);
for(int j=0;j<sz;++j)
{
id=q1[i][j].id; x=q1[i][j].x; y=q1[i][j].y;
now[x][y]=i; ++ans[id];
for(int k=0;k<4;++k)
{
int tx=x+fx[k],ty=y+fy[k];
if(in(tx,ty)&&now[tx][ty]==i) ans[id]-=merge(num(x,y),num(tx,ty));
}
}
}memset(now,-1,sizeof(now));
for(int i=0,sz,id,x,y;i<=maxx;++i)
{
sz=q2[i].size(); if(!sz) continue; clear(n*m);
for(int j=sz-1;j>=0;--j)
{
id=q2[i][j].id; x=q2[i][j].x; y=q2[i][j].y;
now[x][y]=i; --ans[id];
for(int k=0;k<4;++k)
{
int tx=x+fx[k],ty=y+fy[k];
if(in(tx,ty)&&now[tx][ty]==i) ans[id]+=merge(num(x,y),num(tx,ty));
}
}
}
ans[0]=1; for(int i=1;i<=q;++i) printf("%lld
",ans[i]+=ans[i-1]);
return 0;
}
}
signed main(){return yspm::main();}
以上是关于Codeforces1303 F Number of Components的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces1070A Find a Number 图论
Codeforces 1303E - Erase Subsequences
[codeforces]#350F. Restore a Number