今天依舊是墮落無比,早起不了一點。因為白天沒課,直接睡到三點,除了中午起來背了半小時單詞。。。。。
六級單詞
學了too much time 的單詞,感覺現在有印象,但是估計過幾天就忘記了。估計得熟練
資料庫實驗報告
預計9點到12點寫完差不多三分實驗報告?
退役者的每日一題3
題目連結:https://atcoder.jp/contests/abc380/tasks/abc380_e
思路分析:
首先,肯定想到是使用並查集進行維護,但是當時看錯題了,以為是所有和x相同顏色的格子,結果是祥林的。相鄰的其實我並不太會,在參考了別人的題解之後,發現只要額外多開闢兩個陣列即可。這裡總共開闢了五個陣列,cnt,fa,l,r,col分別維護區間塊的點數、父親、左邊界、右邊界以及顏色。對於塊的合併,我們需要當這個塊的顏色改變後,如果和左右相鄰塊的顏色是一樣的,那我們需要將左塊的左邊界變成合並後的左邊界,右塊的右邊界要變成合並後的右邊界即可。
程式碼實現:
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=5e5+10;
const int MAX=1e6+5;
const int mod=1E9+7;
int n,m,k,w;
int fa[N];
int cnt[N],l[N],r[N],col[N];
void init(int n){
for(int i=1;i<=n;i++){
fa[i]=l[i]=r[i]=col[i]=i;
cnt[i]=1;
}
}
int findfa(int x){
if(fa[x]!=x)
return fa[x]=findfa(fa[x]);
return x;
}
void merge(int x,int y){
int fx=findfa(x);
// 中間的
cnt[col[fx]]-=r[fx]-l[fx]+1;
col[fx]=y;
cnt[y]+=r[fx]-l[fx]+1;
// 問右邊
if(r[fx]!=n){
int fr=findfa(r[fx]+1);
if(col[fr]==y){
r[fx]=r[fr];
fa[fr]=fx;
}
}
// 問左邊
if(l[fx]!=1){
int fl=findfa(l[fx]-1);
if(col[fl]==y){
l[fx]=l[fl];
fa[fl]=fx;
}
}
}
void solve(){
int n,q;
cin>>n>>q;
init(n);
int op,x,y;
while(q--){
cin>>op;
if(op==1){
cin>>x>>y;
merge(x,y);
}
else {
cin>>x;
cout<<cnt[x]<<endl;
}
}
}
signed main(){
int t;
t=1;
//cin>>t;
while (t--){
solve();
}
return 0;
}