思路讲解
前置知识:并查集,以及如何维护联通块数量和上下限
主要思路就是我们把颜色相同且连在一起的作为一个联通块,如果对这个联通块进行染色,就把根节点染一下颜色,然后看左界-1颜色和右界+1颜色,看看要不要合并。
至于数颜色数量嘛,需要用到维护的该联通块数量
1 2 3 4 5 6 7 8 9
| inline void changeColor(ll x,ll c){ ll fax=find(x); colorCnt[c]+=Cnt[fax]; colorCnt[color[fax]]-=Cnt[fax]; color[fax]=c; }
|
AC代码
https://atcoder.jp/contests/abc380/submissions/61033055
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| #include <iostream> #include <cstring> #include <algorithm> #include <deque> #include <queue> #include <vector> #include <set> #include <map> #include <cmath> #include <bitset> #include <iterator> #include <random> #include <iomanip> #include <cctype> #include <array>
using namespace std; typedef long long ll; const ll N=static_cast<ll>(5e5)+10; ll n,T,q; ll color[N],fa[N];
ll Cnt[N];
ll colorCnt[N];
struct upBoundLowBound{ ll l,r; }lr[N];
inline ll find(ll x){ if(x>n || x<1) return 0; if(fa[x]==x) return x; fa[x]=find(fa[x]); return fa[x]; }
inline void merge(ll x,ll y){ ll fax=find(x),fay=find(y); if(fax==fay) return; fa[fax]=fay; Cnt[fay]+=Cnt[fax]; lr[fay].l=min(lr[fax].l,lr[fay].l); lr[fay].r=max(lr[fax].r,lr[fay].r); }
inline void changeColor(ll x,ll c){ ll fax=find(x); colorCnt[c]+=Cnt[fax]; colorCnt[color[fax]]-=Cnt[fax]; color[fax]=c; }
int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin>>n>>q; for(int i=1;i<=n;++i){ color[i]=i; fa[i]=i; Cnt[i]=1; colorCnt[i]=1; lr[i].l=i; lr[i].r=i; } for(int _=1;_<=q;++_){ ll op,x,c; cin>>op; if(op==1){ cin>>x>>c; changeColor(x, c); ll lowfa,upfa,fax; fax=find(x); lowfa=find(lr[fax].l-1); upfa=find(lr[fax].r+1); if(color[upfa]==c) merge(x,upfa); if(color[lowfa]==c) merge(x,lowfa); }else{ cin>>c; cout<<colorCnt[c]<<endl; } } return 0; }
|
心路历程(WA,TLE,MLE……)
WA https://atcoder.jp/contests/abc380/submissions/61030202
原因是我们还要维护一个块的上界和下界,以确定他是否和其他联通块因为颜色相同而相连。