Algor之数据结构

并查集

合并集合,判断连通块中点的数量,判断集合中是否有环(只能用于无向图)等

int fa[N],n,m;
bool flag;
int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]);
}


int main(){
    cin>>n>>m;
    rep(i,1,n) fa[i]=i;//
    while(m--){
        int a,b,op;
        cin>>op>>a>>b;
        a=find(a),b=find(b);
        if(op==1){
            if(a==b && !flag) flag=1;
            fa[b]=a;
        } 
        else{
            if(a==b) cout<<"Y\n";
            else cout<<"N\n";
        }
    }
    // judge round
    if(flag) cout<<"Yes\n";
    else cout<<"No\n";
    return 0;
}
4 8
1 4 5
1 1 2
2 3 5
1 3 4
1 2 3
1 1 5
2 1 4
2 3 5

线段树

在这里插入图片描述
在这里插入图片描述

点修改

在这里插入图片描述

区间-查询

记得要加pushdown

在这里插入图片描述

区间-修改

懒标记有助于降低时间复杂度

在这里插入图片描述

Code模板

在这里插入图片描述
P3372 【模板】线段树 1

#define int long long
const int N = 1e5 + 10, mod = 998244353;
#define lc p<<1
#define rc p<<1|1

int n,m,w[N];
struct node{
    int l,r,sum,add;
}tr[N*4];

void pushup(int p){
    tr[p].sum=tr[lc].sum+tr[rc].sum;
}

void pushdown(int p){
    if(tr[p].add){
        tr[lc].sum+=tr[p].add*(tr[lc].r-tr[lc].l+1);//beware:add
        tr[rc].sum+=tr[p].add*(tr[rc].r-tr[rc].l+1);//
        tr[lc].add+=tr[p].add;
        tr[rc].add+=tr[p].add;
        tr[p].add=0;
    }
}

void build(int p,int l,int r){
    tr[p]={l,r,w[l],0};
    if(l==r) return;
    int m=l+r>>1;
    build(lc,l,m);
    build(rc,m+1,r);
    pushup(p);
}

void update(int p,int x,int y,int k){
    if(tr[p].l>=x && tr[p].r<=y){
        tr[p].sum+=(tr[p].r-tr[p].l+1)*k;
        tr[p].add+=k;
        return;
    }
    int m=tr[p].l+tr[p].r>>1;
    pushdown(p);
    if(x<=m) update(lc,x,y,k);
    if(y>m) update(rc,x,y,k);
    pushup(p);
}

int query(int p,int x,int y){
    if(tr[p].l>=x && tr[p].r<=y) return tr[p].sum;
    int m=tr[p].l+tr[p].r>>1;
    pushdown(p);
    int cnt=0;
    if(x<=m) cnt+=query(lc,x,y);//beware
    if(y>m) cnt+=query(rc,x,y);
    return cnt;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin>>n>>m;
    rep(i,1,n) cin>>w[i];

    build(1,1,n);

    while(m--){
        int op,k,x,y;
        cin>>op>>x>>y;
        if(op==2) cout<<query(1,x,y)<<endl;
        else cin>>k,update(1,x,y,k);
    }

    return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值