【学习笔记】关于(数据结构)的一切

并查集

初始化

冰茶姬一定要记得初始化口牙!!!!

int fa[N]; //fa数组记录每个节点的父亲
for(int i=1;i<=n;i++) fa[i]=i; //初始化 每个点的父亲都是自己

路径压缩

int Find(int x) return fa[x]==x ? x : fa[x]=Find(fa[x]); //如果父亲是自己,说明找到头了,否则继续递归向上,并且进行路径压缩,把自己直接挂到根节点上
void Union(int x,int y) {if(Find(x)!=Find(y)) fa[Find(y)]=Find(x);} //如果两个点不在一棵树上,就把一个点的根挂到另一个点的根上

按秩合并(启发式合并)

int siz[N]; //siz数组记录每个树的节点个数
for(int i=1;i<=n;i++) siz[i]=1; //初始状态每个树节点个数都是1
int Find(int x) return fa[x]==x ? x : Find(fa[x]); //同上,但不压缩路径
void Union(int x,int y)
{
    x=Find(x);y=Find(y);
    if(x==y) return ;
    if(siz[x]<size[y]) swap(x,y);
    fa[y]=x;
    siz[x]+=siz[y];//更新树大小
}

线段树

朴素线段树

易错点

1.Pushdown时,孩子的sum需要加上u的lazy tag而不是孩子自己的lazy tag
2.Query和Modify的l,r是不变向下传递的

code

//lg p3372
#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define lc (u<<1)
#define rc ((u<<1)|1)

const int N = (int)1e5+5;

struct node{int l,r;ll sum,lazy;}sg[4*N];

ll a[N];
int n,m;

inline void Pushup(int u) {sg[u].sum=sg[lc].sum+sg[rc].sum;}
inline void Pushdown(int u) 
{
    if(sg[u].lazy) 
    {
        sg[lc].lazy+=sg[u].lazy;
        sg[rc].lazy+=sg[u].lazy;
        sg[lc].sum+=(sg[lc].r-sg[lc].l+1)*sg[u].lazy;
        sg[rc].sum+=(sg[rc].r-sg[rc].l+1)*sg[u].lazy;
        sg[u].lazy=0;
    }
}

void Build(int u,int l,int r)
{
    sg[u]=(node){l,r,0,0};
    if(l==r) {sg[u].sum=a[l];return ;}
    int mid=(l+r)>>1;
    Build(lc,l,mid);
    Build(rc,mid+1,r);
    Pushup(u);
}

ll Query(int u,int l,int r)
{
    if(l<=sg[u].l && r>=sg[u].r) return sg[u].sum;
    Pushdown(u);
    int mid=(sg[u].l+sg[u].r)>>1;
    ll sum=0;
    if(l<=mid) sum+=Query(lc,l,r);
    if(r>=mid+1) sum+=Query(rc,l,r);
    return sum;
}

void Modify(int u,int l,int r,ll x)
{
    if(l<=sg[u].l && r>=sg[u].r) {sg[u].lazy+=x,sg[u].sum+=x*(sg[u].r-sg[u].l+1);return ;}
    int mid=(sg[u].l+sg[u].r)>>1;
    Pushdown(u);
    if(l<=mid) Modify(lc,l,r,x);
    if(r>=mid+1) Modify(rc,l,r,x);
    Pushup(u);
}

int main()
{
    // freopen("working.in","r",stdin);
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);    
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    Build(1,1,n);
    while(m--)
    {
        int opt,l,r;
        cin>>opt;
        if(opt==1) {int k; cin>>l>>r>>k; Modify(1,l,r,k);}
        else {cin>>l>>r; cout<<Query(1,l,r)<<endl;}
    }
    return 0;
}
posted @ 2024-02-19 10:51  yeyou26  阅读(29)  评论(4编辑  收藏  举报