重新振作第8天----日常小记

今天依旧是堕落无比,早起不了一点。因为白天没课,直接睡到三点,除了中午起来背了半小时单词。。。。。

六级单词

学了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;
}
posted @   菜dog的日常生活  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示