基础数据结构_模板

1.树状数组


int tree[100005];//树
int lowbit(int x)//lowbit
{
    return x&(-x);
}
int sum(int x)//求和求的是比当前数小的数字之和,至于这里如何实现,很简单:int sum=sum(a[i]);
{
    int sum=0;
    while(x>0)
    {
        sum+=tree[x];
        x-=lowbit(x);
    }
    return sum;
}
void add(int x,int c)//加数据。
{
    while(x<=n)
    {
        tree[x]+=c;
        x+=lowbit(x);
    }
}

2.二维树状数组


int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int y,int d)
{
    int temp=y;
    while(x<=m)
    {
        y=temp;
        while(y<=m)
        {
            a[x][y]+=d;
            y=y+lowbit(y);
        }
        x=x+lowbit(x);

    }

}
int getsum(int x,int y)
{
    int sum=0;
    int temp=y;
    while(x>0)
    {
        y=temp;
        while(y>0)
        {
            sum=sum+a[x][y];
            y=y-lowbit(y);
        }
        x=x-lowbit(x);
    }
    return sum;

}
update(x+1,y+1,d);

3.线段树

#define lson l,m,rt*2
#define rson m+1,r,rt*2+1

void pushup(int rt)
{
    tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
int Query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        return tree[rt];
    }
    else
    {
        int m=(l+r)>>1;
        int ans=0;
        if(L<=m)
        {
            ans+=Query(L,R,lson);
        }
        if(m<R)
        {
            ans+=Query(L,R,rson);
        }
        return ans;
    }
}
void build( int l ,int r , int rt )
{
	if( l == r )
	{
		scanf("%d",&tree[rt]);
		return ;
	}
	else
	{
		int m = (l+r)>>1 ;
		build(lson) ;
		build(rson) ;
		pushup(rt) ;
	}
}
void update(int p,int c,int l,int r,int rt)//p阵营c数据.
{
    //printf("%d %d %d %d %d\n",p,c,l,r,rt);
    if(l==r)
    {
        tree[rt]+=c;
    }
    else
    {
        int m=(l+r)>>1;
        if(p<=m) update(p,c,lson);
        else  update(p,c,rson);
        pushup(rt);
		//printf("sum[%d]:%d\n",rt,tree[rt]);
    }
}
int query(int L, int R, int l, int r, int rt, int *pos)//返回位子
{
    if (L <= l && r <= R)
    {
        *pos = posn[rt];
        return tree[rt];
    }
    else
    {
        int m = (l + r) >> 1;
        int ret1 = INT_MIN;
        int ret2 = INT_MIN;
        int pa, pb;
        int *pos1 = &pa;
        int *pos2 = &pb;
        if (L <= m)
        {
            ret1 = query(L, R,  lson, pos1);
        }
        if (R > m)
        {
            ret2 = query(L, R, rson, pos2);
        }
        if (ret1 > ret2)
        {
            *pos = pa;
        }
        else
        {
            *pos = pb;
            ret1 = ret2;
        }
        return ret1;
    }
}
int pos;
printf("%d %d\n", pos, query(1, n, 1, n, 1, &pos));

4.线段树区间更新

#include<stdio.h>
#include<string.h>
using namespace std;
#define lson l,m,rt*2
#define rson m+1,r,rt*2+1
#define ll long long int
ll tree[1212112];
ll flag[1212112];
void pushdown(int l,int r,int rt)//向下维护树内数据
{
    if(flag[rt])//如果贪婪标记不是0(说明需要向下进行覆盖区间(或点)的值)
    {
        int m=(l+r)/2;
        flag[rt*2]+=flag[rt];
        flag[rt*2+1]+=flag[rt];
        tree[rt*2]+=(m-l+1)*flag[rt];//千万理解如何覆盖的区间值(对应线段树的图片理解(m-l)+1)是什么意识.
        tree[rt*2+1]+=(r-(m+1)+1)*flag[rt];
        flag[rt]=0;
    }
}
void pushup(int rt)
{
    tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
void build( int l ,int r , int rt )
{      
    flag[rt]=0;
	if( l == r )
	{
		scanf("%lld",&tree[rt]);
		return ;
	}
	else
	{
		int m = (l+r)>>1 ;
		build(lson) ;
		build(rson) ;
		pushup(rt) ;
		return ;
	}
}
ll Query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        return tree[rt];
    }
    else
    {
        pushdown(l,r,rt);
        int m=(l+r)>>1;
        ll ans=0;
        if(L<=m)
        {
            ans+=Query(L,R,lson);
        }
        if(m<R)
        {
            ans+=Query(L,R,rson);
        }
        pushup(rt);
        return ans;
    }
}
void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R)//覆盖的是区间~
    {
        tree[rt]+=c*((r-l)+1);//覆盖当前点的值
        flag[rt]+=c;//同时懒惰标记~!
        return ;
    }
    pushdown(l,r,rt);
    int m=(l+r)/2;
    if(L<=m)
    {
        update(L,R,c,lson);
    }
    if(m<R)
    {
        update(L,R,c,rson);
    }
    pushup(rt);
}
int main()
{
     int n,m;
     while(~scanf("%d%d",&n,&m))
     {
         memset(flag,0,sizeof(flag));
         memset(tree,0,sizeof(tree));
         build(1,n,1);
         for(int i=0;i<m;i++)
         {
             char s[5];
             int x,y;
             scanf("%s%d%d",s,&x,&y);
             if(s[0]=='Q')
             {
                 printf("%lld\n",Query(x,y,1,n,1));
             }
             if(s[0]=='C')
             {
                 ll c;
                 scanf("%lld",&c);
                 update(x,y,c,1,n,1);
             }
         }
     }
}


线段树查询最大值位子


#include<cstdio>
#include<climits>
#include<algorithm>

using namespace std;

#define lson l, m, rt<<1
#define rson m+1, r, (rt<<1)|1

int tree[111111<<2];
int posn[111111<<2];
void pushup(int rt)
{
    if (tree[rt<<1] > tree[rt<<1|1])
    {
        tree[rt] = tree[rt<<1];
        posn[rt] = posn[rt<<1];
    }
    else
    {
        tree[rt] = tree[rt<<1|1];
        posn[rt] = posn[rt<<1|1];
    }
}
void build(int l, int r, int rt)
{
    if (l == r)
    {
        scanf("%d", &tree[rt]);
        posn[rt] = l;
    }
    else
    {
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        pushup(rt);
    }
}
void update(int p, int val, int l, int r, int rt)
{
    if (l == r)
    {
        tree[rt] = val;
    }
    else
    {
        int m = (l + r) >> 1;
        if (p <= m)
        {
            update(p, val, lson);
        }
        else
        {
            update(p, val, rson);
        }
        pushup(rt);
    }
}
int query(int L, int R, int l, int r, int rt, int *pos)
{
    if (L <= l && r <= R)
    {
        *pos = posn[rt];
        return tree[rt];
    }
    else
    {
        int m = (l + r) >> 1;
        int ret1 = INT_MIN;
        int ret2 = INT_MIN;
        int pa, pb;
        int *pos1 = &pa;
        int *pos2 = &pb;
        if (L <= m)
        {
            ret1 = query(L, R,  lson, pos1);
        }
        if (R > m)
        {
            ret2 = query(L, R, rson, pos2);
        }
        if (ret1 > ret2)
        {
            *pos = pa;
        }
        else
        {
            *pos = pb;
            ret1 = ret2;
        }
        return ret1;
    }
}
int main(void)
{
    int n, m;

    while (scanf("%d", &n) != EOF)
    {
        build(1, n, 1);

        scanf("%d", &m);
        char op[2];
        int a, b;
        while (m--)
        {
            scanf("%s", op);
            if (op[0] == 'Q')
            {
                int pos;
                printf("%d %d\n", pos, query(1, n, 1, n, 1, &pos));
            }
            else
            {
                scanf("%d%d", &a, &b);
                update(a, b, 1, n, 1);
            }
        }
        printf("\n");
    }

    return 0;
}



5.字典树

void creattrie(char *str)
{
    int len=strlen(str);
    tire *p=root,*q;
    for(int i=0;i<len;i++)
    {
        int id=str[i]-'0';
        if(p->next[id]==NULL)
        {
            q=(trie *)malloc(sizeof(trie));
            q->v=1;
            for(int j=0;j<maxn;j++)
            {
                q->next[j]=NULL;
            }
            p->next[id]=q;
            p=p->next[id];
        }
        else 
        {
            p->next[id]->v++;
            p=p->next[id];
        }
    }
    p->v=-1;
}
int findtrie(char *str)
{
    int len=strlen(str);
    trie *p=root;
    for(int i=0;i<maxn;i++)
    {
        int id=str[i]-'0';
        p=p->next;
        if(p==NULL)
        return 0;
        if(p->v==-1)
        {
            return -1;
        }
    }
    return -1;
}
int dealTrie(Trie* T)
{
    int i;
    if(T==NULL)
        return 0;
    for(i=0;i<MAX;i++)
    {
        if(T->next[i]!=NULL)
            deal(T->next[i]);
    }
    free(T);
    return 0;
}


6.字典树
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
#define maxn 26//只包含小写字母、
typedef struct tree
{
    int flag;
    tree *next[maxn];
    char  la[30];
}tree;
tree root;

void creat(char *str)
{
    int len=strlen(str);
    tree *p=&root,*q;
    for(int i=0;i<len;i++)
    {
        int id=str[i]-'a';
        if(p->next[id]==NULL)
        {
            q=(tree *)malloc(sizeof(root));
            q->v=1;
            for(int j=0;j<26;j++)
            {
                q->next[j]=NULL;
            }
            p->next[id]=q;
        }
        else
        {
            p->next[id]->v++;
        }
            p=p->next[id];
    }
}
int find(char *str)
{
    int len=strlen(str);
    tree *p=&root;
    for(int i=0;i<len;i++)
    {
        int id=str[i]-'a';
        p=p->next[id];
        if(p==NULL)
        return 0;
    }
    return p->v;
}
    char str[15];  
    int i;  
    for(int i=0;i<26;i++)  
    {  
        root.next[i]=NULL;  
    }  
void Freedom(tree* p)
{
    int i;
    for(i=0;i<52;i++){
        if(p->next[i]!=NULL)
            Freedom(p->next[i]);
    }
    free(p);
}
        Freedom(&root);


01字典树贪心查询,建立,删除

#define maxn 2
typedef struct tree
{
    tree *nex[maxn];
    int v;
    int val;
}tree;
tree root;
void init()
{
    for(int i=0;i<maxn;i++)
    {
        root.nex[i]=NULL;
    }
}
void creat(char *str,int va)
{
    int len=strlen(str);
    tree *p=&root,*q;
    for(int i=0;i<len;i++)
    {
        int id=str[i]-'0';
        if(p->nex[id]==NULL)
        {
            q=(tree *)malloc(sizeof(root));
            q->v=1;
            for(int j=0;j<2;j++)
            {
                q->nex[j]=NULL;
            }
            p->nex[id]=q;
        }
        else
        {
            p->nex[id]->v++;
        }
        p=p->nex[id];
        if(i==len-1)
        {
            p->val=va;
        }
    }
}
void del(char *str)
{
    int len=strlen(str);
    tree *p=&root;
    for(int i=0;i<len;i++)
    {
        int id=str[i]-'0';
        p->nex[id]->v--;
        tree *tmp=p->nex[id];
        if(p->nex[id]->v==0)
        {
            p->nex[id]=NULL;
        }
        p=tmp;
    }
    return ;
}
void find(char *str,int query)
{
    int len=strlen(str);
    tree *p=&root;
    for(int i=0;i<len;i++)
    {
        int id=str[i]-'0';
        if(p->nex[1-id]!=0)
        {
            p=p->nex[1-id];
        }
        else
        p=p->nex[id];
        if(p==NULL)
        return ;
        if(i==len-1)printf("%d\n",p->val^query);
    }
}




7.并查集


int find(int a)
{
    int r=a;
    while(f[r]!=r)
    r=f[r];
    int i=a;
    int j;
    while(i!=r)
    {
        j=f[i];
        f[i]=r;
        i=j;
    }
    return r;
}
int find(int x)
{
    return f[x] == x ? x : (f[x] = find(f[x]));
}
void merge(int a,int b)
{
    int A,B;
    A=find(a);
    B=find(b);
    if(A!=B)
    f[B]=A;
}

8.带权并查集


#include<stdio.h>
#include<string.h>
using namespace std;
int f[1000010];
int sum[1000010];
int find(int x)
{
    if(x!=f[x])
    {
        int pre=f[x];//pre是x的一个父节点。
        f[x]=find(f[x]);//递归找祖先。
        sum[x]+=sum[pre];
    }
    return f[x];
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0;i<=n;i++)
        {
            f[i]=i;
            sum[i]=0;
        }
        int op;
        while(n--)
        {
            scanf("%d",&op);
            if(op==1)
            {
                int x,y,val;
                scanf("%d%d%d",&x,&y,&val);
                int X=find(x);
                int Y=find(y);
                if(X!=Y)
                {
                    sum[Y]=val-sum[y]+sum[x];
                    f[Y]=X;
                }
            }
            else 
            {
                int x,y;
                scanf("%d%d",&x,&y);
                int X=find(x);
                int Y=find(y);
                if(X!=Y)
                {
                    printf("?\n");
                }
                else
                {
                    printf("%d\n",sum[y]-sum[x]);
                }
            }
        }
    }
}

9.树链剖分基础操作:

void Dfs(int u,int from,int d)  
{  
    depth[u]=d;size[u]=1;fa[u]=from;  
//    if(fa[u]==-1)fa[u]=1;  
    int maxn=0;  
    for(int i=0;i<mp[u].size();i++)  
    {  
        int v=mp[u][i];  
        if(v==from)continue;  
        Dfs(v,u,d+1);  
        size[u]+=size[v];  
        if(son[u]==-1||size[v]>maxn)  
        {  
            maxn=size[v];  
            son[u]=v;  
        }  
    }  
}  
void Dfs2(int u,int from,int top)  
{  
    Top[u]=top;dfn[u]=++cnt;  
    if(son[u]!=-1)  
    {  
        Dfs2(son[u],u,top);  
    }  
    for(int i=0;i<mp[u].size();i++)  
    {  
        int v=mp[u][i];  
        if(v==from||v==son[u])continue;  
        Dfs2(v,u,v);  
    }  
}  
void Slove(int x,int y,int change)  
{  
    int fx=Top[x];  
    int fy=Top[y];  
    while(fx!=fy)  
    {  
        if(depth[fx]<depth[fy])  
        {  
            swap(fx,fy);  
            swap(x,y);  
        }  
        update(dfn[fx],dfn[x],change,1,n,1);  
        x=fa[fx];fx=Top[x];  
    }  
    if(depth[x]>depth[y])  
    {  
        swap(x,y);  
    }  
    update(dfn[x],dfn[y],change,1,n,1);  
}  

void Slove(int x,int y)  
{  
    int sum=0;  
    int fx=Top[x],fy=Top[y];  
    while(fx!=fy)  
    {  
        if(depth[fx]<depth[fy])  
        {  
            swap(fx,fy);  
            swap(x,y);  
        }  
        sum+=Query(dfn[fx],dfn[x],1,n,1);  
        x=fa[fx];fx=Top[x];  
    }  
    if(x==y)  
    {  
        printf("%d\n",sum);  
        return ;  
    }  
    if(depth[x]<depth[y])swap(x,y);  
    sum+=Query(dfn[son[y]],dfn[x],1,n,1);  
    printf("%d\n",sum);  
}  








  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值