基礎資料結構_模板__基礎資料結構_模板

來源:互聯網
上載者:User

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+1void 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 intll 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)|1int 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 2typedef 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);  }  








聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.