高级数据结构模板

1.线段树

//Twenty
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define lc x<<1
#define rc x<<1|1
#define mid ((l+r)>>1)
using namespace std;
const int maxn=2e6+10;
typedef long long ll;
ll a[maxn],segt[maxn<<2],lazy[maxn<<2];
int n,q,qu,xx,yy,zz;
void build(int x,int l,int r){
    if(l==r){segt[x]=a[l];return ;}
    build(lc,l,mid);build(rc,mid+1,r);
    segt[x]=segt[lc]+segt[rc];
}
void putdown(int x,int l_len,int r_len){
    segt[lc]+=lazy[x]*l_len;lazy[lc]+=lazy[x];
    segt[rc]+=lazy[x]*r_len;lazy[rc]+=lazy[x];
    lazy[x]=0;
}
void updata(int x,int l,int r,int ql,int qr,int v){
    if(ql<=l&&r<=qr){segt[x]+=(r-l+1)*v;lazy[x]+=v;return;}
    if(lazy[x]) putdown(x,mid-l+1,r-mid);
    if(ql<=mid) updata(lc,l,mid,ql,qr,v);
    if(qr>mid) updata(rc,mid+1,r,ql,qr,v);
    segt[x]=segt[lc]+segt[rc];
}
ll query(int x,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr) return segt[x];
    if(lazy[x]) putdown(x,mid-l+1,r-mid);
    if(qr<=mid) return query(lc,l,mid,ql,qr);
    else if(ql>mid) return query(rc,mid+1,r,ql,qr);
    return query(lc,l,mid,ql,qr)+query(rc,mid+1,r,ql,qr);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    build(1,1,n);
    scanf("%d",&q);
    while(q--){
        scanf("%d%d%d",&qu,&xx,&yy);
        if(qu==1){
        scanf("%d",&zz);
            updata(1,1,n,xx,yy,zz);
        }
        else printf("%lld\n",query(1,1,n,xx,yy));
    }
    return 0;
}

codevs 线段树练习3

//Twenty
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define lc x<<1
#define rc x<<1|1
#define mid ((l+r)>>1)
using namespace std;
const int maxn=1e6+10;
typedef long long ll;
ll a[maxn],segt[maxn<<2][7],lazy[maxn<<2],temp[7];
int n,q,xx,yy,zz;
char qu[10];
using namespace std;
void build(int x,int l,int r){
    if(l==r) {segt[x][a[l]%7]=1; return ;}
    build(lc,l,mid);build(rc,mid+1,r);
    for(int i=0;i<=6;i++){segt[x][i]=segt[lc][i]+segt[rc][i];}
}
void putdown(int x){
    lazy[lc]+=lazy[x];
    for(int i=0;i<=6;i++) temp[(i+lazy[x])%7]=segt[lc][i];
    for(int i=0;i<=6;i++) segt[lc][i]=temp[i];
    lazy[rc]+=lazy[x];
    for(int i=0;i<=6;i++) temp[(i+lazy[x])%7]=segt[rc][i];
    for(int i=0;i<=6;i++) segt[rc][i]=temp[i];
    lazy[x]=0;
}

void updata(int x,int l,int r,int ql,int qr,int v){
    if(ql<=l&&r<=qr) {
    for(int i=0;i<=6;i++) temp[(i+v)%7]=segt[x][i];
    for(int i=0;i<=6;i++) segt[x][i]=temp[i];
    lazy[x]+=v; return ; }
    if(lazy[x]) putdown(x);
    if(ql<=mid) updata(lc,l,mid,ql,qr,v);
    if(qr>mid) updata(rc,mid+1,r,ql,qr,v);
    for(int i=0;i<=6;i++) segt[x][i]=segt[lc][i]+segt[rc][i];
}
ll query(int x,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr) return segt[x][0];
    if(lazy[x]) putdown(x);
    if(qr<=mid) return query(lc,l,mid,ql,qr);
    else if(ql>mid) return query(rc,mid+1,r,ql,qr);
    return query(lc,l,mid,ql,qr)+query(rc,mid+1,r,ql,qr);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    build(1,1,n);
    scanf("%d",&q);
    while(q--){
        scanf("%s%d%d",&qu,&xx,&yy);
        if(qu[0]==‘a‘){
        scanf("%d",&zz);
            updata(1,1,n,xx,yy,zz);
        }
        else printf("%lld\n",query(1,1,n,xx,yy));
    }
    return 0;
}

codevs 线段树练习4

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#define lc x<<1
#define rc x<<1|1
#define mid ((l+r)>>1)
const int maxn=200050;
typedef long long ll;
char s[10];
ll tmp,nn,qs,a,b,c,n,m;
ll aa[maxn],sgt[maxn<<2],sgd[maxn<<2],sgx[maxn<<2],lzj[maxn<<2],lzc[maxn<<2];
using namespace std;
inline ll read(){
    ll ret=0,f=1; char ch=getchar();
    while(ch!=‘-‘&&(ch>‘9‘||ch<‘0‘)) ch=getchar();
    if(ch==‘-‘) {f=-1;ch=getchar();}
    for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) ret=ret*10+ch-‘0‘;
    return ret*f;
}
void down(int x,int len,int l_len,int r_len){
     if(lzc[x]) {
     if(lzj[x]) tmp=(sgt[x]-lzj[x]*len)/len;
     else tmp=sgt[x]/len;
     sgt[lc]=tmp*l_len; lzc[lc]=1; lzj[lc]=0;
     sgd[lc]=sgx[lc]=tmp;
     sgt[rc]=tmp*r_len; lzc[rc]=1; lzj[rc]=0;
     sgd[rc]=sgx[rc]=tmp;
     lzc[x]=0;
     }
     if(lzj[x]){
        sgt[lc]+=lzj[x]*l_len; lzj[lc]+=lzj[x];
        sgt[rc]+=lzj[x]*r_len; lzj[rc]+=lzj[x];
        sgd[lc]+=lzj[x]; sgx[lc]+=lzj[x]; sgd[rc]+=lzj[x]; sgx[rc]+=lzj[x];
     lzj[x]=0;
     }
}
void build(int x,int l,int r){
    if(l==r) {sgd[x]=sgx[x]=sgt[x]=aa[l];return;}
    build(lc,l,mid); build(rc,mid+1,r);
    sgt[x]=sgt[lc]+sgt[rc];
    sgd[x]=max(sgd[lc],sgd[rc]);
    sgx[x]=min(sgx[lc],sgx[rc]);
}
void add(int x,int ql,int qr,int l,int r,int v,int cj){
    if(l>=ql&&r<=qr) {
        if(cj==1) {sgt[x]+=v*(r-l+1);  lzj[x]+=v;
        sgd[x]+=v; sgx[x]+=v;
        }
        else {sgt[x]=v*(r-l+1);  lzc[x]=1; lzj[x]=0;
        sgd[x]=sgx[x]=v;
        }
        return;
    }
    if(lzj[x]||lzc[x]) down(x,r-l+1,mid-l+1,r-mid);
    if(ql<=mid) add(lc,ql,qr,l,mid,v,cj);
    if(qr>mid) add(rc,ql,qr,mid+1,r,v,cj);
    sgt[x]=sgt[lc]+sgt[rc];
    sgd[x]=max(sgd[lc],sgd[rc]);
    sgx[x]=min(sgx[lc],sgx[rc]);
}
ll query(int x,int ql,int qr,int l,int r,int cs){
    if(l>=ql&&r<=qr)
    {if(cs==1) return sgd[x];
     if(cs==2) return sgx[x];
     if(cs==3) return sgt[x];
    }
    if(lzj[x]||lzc[x]) down(x,r-l+1,mid-l+1,r-mid);
    if(qr<=mid) return query(lc,ql,qr,l,mid,cs);
    else if(ql>mid) return query(rc,ql,qr,mid+1,r,cs);
    else {if(cs==3)return query(lc,ql,qr,l,mid,cs)+query(rc,ql,qr,mid+1,r,cs);
          if(cs==1) return max(query(lc,ql,qr,l,mid,cs),query(rc,ql,qr,mid+1,r,cs));
          if(cs==2) return min(query(lc,ql,qr,l,mid,cs),query(rc,ql,qr,mid+1,r,cs));
    }
}
int main()
{
    n=read(); m=read();
    for(int i=1;i<=n;i++) aa[i]=read();
    build(1,1,n);
    for(int i=1;i<=m;i++){
     scanf("%s",&s); a=read();b=read();
     if(s[0]==‘a‘) add(1,a,b,1,n,read(),1);
     else if(s[1]==‘e‘) add(1,a,b,1,n,read(),2);
     else if(s[1]==‘a‘) printf("%lld\n",query(1,a,b,1,n,1));
     else if(s[1]==‘i‘) printf("%lld\n",query(1,a,b,1,n,2));
     else printf("%lld\n",query(1,a,b,1,n,3));
   }
   return 0;
}

codevs 线段树练习5

2.树状数组

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn=500000+5;
int n,m,x,y,k,c[maxn];
int lowbit(int x){
    return x&(-x);
}
void add(int x,int v){
    for(int i=x;i<=n;i=i+lowbit(i)) c[i]+=v;
}
int sum(int x){
    int ans=0;
    for(int i=x;i>=1;i=i-lowbit(i)) ans+=c[i];
    return ans;
}
int main()
{
   scanf("%d%d",&n,&m);
   for(int i=1;i<=n;i++)
   {
        scanf("%d",&x);
        add(i,x);
   }
   while(m--){
       scanf("%d%d%d",&k,&x,&y);
       if(k==1) add(x,y);
       else  printf("%d\n",sum(y)-sum(x-1));
   }
   return 0;
}

洛谷 树状数组

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=500000+5;
using namespace std;
int n,m,x,y,k,v,tmp,c[maxn];
int lowbit(int x){
    return x&(x^(x-1));
}
void add(int x,int v){
    for(int i=x;i<=n;i+=lowbit(i)) c[i]+=v;
}
int sum(int x){
    int ans=0;
    for(int i=x;i>0;i-=lowbit(i)) ans+=c[i];
    return ans;
}
int main()
{
   ios::sync_with_stdio(false);
   cin>>n>>m;
   for(int i=1;i<=n;i++){
       cin>>x;
       add(i,x-tmp);
       tmp=x;
   }
   while(m--){
       cin>>k>>x;
       if(k==1){
           cin>>y>>v;
           add(x,v);
           add(y+1,-v);
       }
    else{
       cout<<sum(x)<<endl;
    }
   }
   return 0;
}

洛谷 树状数组2 差分

//Twenty
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100025;
int sum[maxn],T,q[maxn],qs[maxn],a[maxn],xx,n,sz;
int hash(int x){ return lower_bound(a+1,a+sz+1,x)-a;}
void add(int x,int v){ for(int i=x;i<=sz;i+=(i&(-i))) sum[i]+=v; }
int qry(int x) {int res=0; for(int i=x;i>=1;i-=(i&(-i))) res+=sum[i]; return res;}
int kth(int k) {
  int res=0;
  for(int i=20;i>=0;i--){
   res+=(1<<i);
   if(res>=sz||k<=sum[res]) res-=(1<<i); //同种数有多个 不能直接查k 故查比k小的+1
   else k-=sum[res];
  }
  return a[res+1];
}
int main()
{
   scanf("%d",&T);
   for(int i=1;i<=T;i++){
     scanf("%d%d",&q[i],&qs[i]);
     if(q[i]!=4) a[++sz]=qs[i];
   }
   sort(a+1,a+sz+1);
   sz=unique(a+1,a+sz+1)-(a+1);
   for(int i=1;i<=T;i++){
    switch(q[i]){
    case 1:add(hash(qs[i]),1);break;
    case 2:add(hash(qs[i]),-1);break;
    case 3:printf("%d\n",qry(hash(qs[i])-1)+1);break;
    case 4:printf("%d\n",kth(qs[i]));break;
    case 5:printf("%d\n",kth(qry(hash(qs[i])-1)));break; //注意区分5,6
    case 6:printf("%d\n",kth(qry(hash(qs[i]))+1));break;
    }
   }
   return 0;
}

树状数组普通平衡树

3.ZKW线段树

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=200005;
int m=1,x,y,T,n,a[maxn<<2];
char q[10];
using namespace std;
void build(){
    for(;m<=n+1;m<<=1);
    for(int i=m+1;i<=m+n;i++) scanf("%d",&a[i]);
    for(int i=m-1;i>0;i--) a[i]=a[i<<1]+a[i<<1|1];
}
void add(int x,int v){
    int k=x+m; a[k]+=v;
    for(k>>=1;k;k>>=1) a[k]=a[k<<1]+a[k<<1|1];
}
int query(int l,int r){
    int ret=0;
    for(int i=m+l-1,j=m+r+1;i^j^1;i>>=1,j>>=1){
        if(~i&1) ret+=a[i^1];
        if(j&1) ret+=a[j^1];
    }
    return ret;
}
int main()
{
   scanf("%d",&T);
   for(int t=1;t<=T;t++){
       scanf("%d",&n);
    cout<<"Case "<<t<<":"<<endl;
       build();
       for(;;){
           scanf("%s",&q);
           if(q[0]==‘E‘) break;
           scanf("%d%d",&x,&y);
           if(q[0]==‘A‘) add(x,y);
           else if(q[0]==‘S‘) add(x,-y);
           else printf("%d\n",query(x,y));
       }
       m=1;memset(a,0,sizeof(a));
   }
   return 0;
}

zkw线段树 sum

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=200005;
int f,m=1,x,y,T,n,a[maxn<<2];
char q[5];
using namespace std;
void build(){
    for(;m<=n+1;m<<=1);
    for(int i=m+1;i<=m+n;i++) scanf("%d",&a[i]);
    for(int i=m-1;i>0;i--) a[i]=max(a[i<<1],a[i<<1|1]);
}
void add(int x,int v){
    int k=x+m; a[k]=v;
    for(k>>=1;k;k>>=1) a[k]=max(a[k<<1],a[k<<1|1]);
}
int query(int l,int r){
    int ret=0;
    for(int i=m+l-1,j=m+r+1;i^j^1;i>>=1,j>>=1){
        if(~i&1) ret=max(ret,a[i^1]);
        if(j&1) ret=max(ret,a[j^1]);
    }
    return ret;
}
int main()
{
   while(scanf("%d%d",&n,&f)!=EOF){
       build();
       while(f--){
           scanf("%s%d%d",&q,&x,&y);
           if(q[0]==‘U‘) add(x,y);
           else printf("%d\n",query(x,y));
       }
       m=1;memset(a,0,sizeof(a));
   }
   return 0;
}

zkw线段树 max

4.ST表

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=1e6+299;
using namespace std;
int n,m,l,r,st[maxn][20];
void make_st(){
    for(int j=1;j<=20;j++)
      for(int i=1;i+(1<<j)-1<=n;i++)
        st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
int query(int l,int r){
    int k=0;
    while(l+(1<<k)-1<=r) k++;
    if(k) k--;
    return max(st[l][k],st[r-(1<<k)+1][k]);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&st[i][0]);
    make_st();
    while(m--){
        scanf("%d%d",&l,&r);
        printf("%d\n",query(l,r));
    }
    return 0;
}

st表

5.主席树

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=100005;
int sz,T,n,m,rt[maxn],tot,lc[maxn*20],rc[maxn*20],sum[maxn*20],a[maxn],b[maxn];
using namespace std;
void update(int &o,int l,int r,int last,int v){
    o=++tot;
    lc[o]=lc[last];
    rc[o]=rc[last];
    sum[o]=sum[last]+1;
    if(l==r) return;
    int mid=(l+r)>>1;
    if(v<=mid) update(lc[o],l,mid,lc[last],v);
    else update(rc[o],mid+1,r,rc[last],v);
}
int query(int ql,int qr,int l,int r,int k){
    if(l==r) return l;
    int mid=(l+r)>>1;
    int cnt=sum[lc[qr]]-sum[lc[ql]];
    if(cnt>=k) return query(lc[ql],lc[qr],l,mid,k);
    else return query(rc[ql],rc[qr],mid+1,r,k-cnt);
}
int main()
{
     scanf("%d%d",&n,&m);
     for(int i=1;i<=n;i++) { scanf("%d",&a[i]);b[i]=a[i];}
     sort(b+1,b+n+1);
     sz=unique(b+1,b+n+1)-(b+1);
     tot=0;
     rt[0]=++tot;
     //build(rt[0],1,sz);
     for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+sz+1,a[i])-b;
     for(int i=1;i<=n;i++) update(rt[i],1,sz,rt[i-1],a[i]);
     for(int i=1;i<=m;i++){
       int l,r,k;scanf("%d%d%d",&l,&r,&k);
       printf("%d\n",b[query(rt[l-1],rt[r],1,sz,k)]);
     }
   return 0;
}

主席树

6.树链剖分

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#define rc x<<1|1
#define lc x<<1
#define mid ((l+r)>>1)
using namespace std;
const int maxn=150005;
int x,y,z,k,n,q,s,mod,w[maxn],fir[maxn],next[maxn*2],to[maxn*2],father[maxn],R[maxn],size[maxn],tid[maxn];
int top[maxn],e[maxn],in[maxn],segt[maxn<<2],lazy[maxn<<2];
int ecnt,tot;
inline void add(int u,int v){
    next[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v;in[u]++;
    next[++ecnt]=fir[v];fir[v]=ecnt;to[ecnt]=u;in[v]++;
}
void down(int x,int l_len,int r_len){
    if(l_len) lazy[lc]+=lazy[x]%mod, segt[lc]+=l_len*lazy[x]%mod;
    if(r_len) lazy[rc]+=lazy[x]%mod, segt[rc]+=r_len*lazy[x]%mod;
    lazy[x]=0;
}
void change(int x,int l,int r,int ql,int qr,int v){
    if(l>=ql&&r<=qr) {segt[x]+=v*(r-l+1);lazy[x]+=v;lazy[x]%=mod;return;}
    if(lazy[x]) down(x,mid-l+1,r-mid);
    if(ql<=mid) change(lc,l,mid,ql,qr,v);
    if(qr>mid) change(rc,mid+1,r,ql,qr,v);
    segt[x]=(segt[lc]+segt[rc])%mod;
}
int query(int x,int l,int r,int ql,int qr){
    if(l>=ql&&r<=qr) return segt[x];
    if(lazy[x]) down(x,mid-l+1,r-mid);
    if(qr<=mid) return query(lc,l,mid,ql,qr)%mod;
    if(ql>mid) return query(rc,mid+1,r,ql,qr)%mod;
    return (query(lc,l,mid,ql,qr)+query(rc,mid+1,r,ql,qr))%mod;
}
void dfs(int x,int fa){
    father[x]=fa;R[x]=R[fa]+1;size[x]=1;
    for(int i=fir[x];i;i=next[i]){
        if(to[i]!=fa){
            dfs(to[i],x);
            size[x]+=size[to[i]];
            }
    }
}
void dfs2(int x){
    tid[x]=++tot;
    change(1,1,n,tot,tot,w[x]);
    int mson=0;
    if(in[x]==1&&x!=s){
        e[x]=x;
        return;
    }
    for(int i=fir[x];i;i=next[i])
    if(size[to[i]]<size[x]&&size[to[i]]>size[mson]) mson=to[i];
    top[mson]=top[x];
    dfs2(mson); e[x]=e[mson];
    for(int i=fir[x];i;i=next[i]){
        if(size[to[i]]<size[x]&&to[i]!=mson){
            top[to[i]]=to[i];
            dfs2(to[i]);
            e[x]=e[to[i]];
        }
    }
}

void schange(int x,int y,int z){
    while(top[x]!=top[y]){
        if(R[top[x]]<R[top[y]]) swap(x,y);
        change(1,1,n,tid[top[x]],tid[x],z);
        x=father[top[x]];
    }
    if(tid[x]>tid[y]) swap(x,y);
    change(1,1,n,tid[x],tid[y],z);
}

int squery(int x,int y){
    int ret=0;
    while(top[x]!=top[y]){
        if(R[top[x]]<R[top[y]]) swap(x,y);
        ret+=query(1,1,n,tid[top[x]],tid[x]); ret=ret%mod;
        x=father[top[x]];
    }
    if(tid[x]>tid[y]) swap(x,y);
    ret+=query(1,1,n,tid[x],tid[y]); ret=ret%mod;
    return ret;
}

int main()
{
   scanf("%d%d%d%d",&n,&q,&s,&mod);
   for(int i=1;i<=n;i++) scanf("%d",&w[i]);
   for(int i=1;i<n;i++){
        scanf("%d%d",&x,&y);
        add(x,y);
   }
   father[s]=s;top[s]=s;
   dfs(s,s);dfs2(s);
   for(int i=1;i<=q;i++){
       scanf("%d",&k);
       if(k==1){
           scanf("%d%d%d",&x,&y,&z);
           schange(x,y,z);

    }
    else if(k==2){
        scanf("%d%d",&x,&y);
           printf("%d\n",squery(x,y));
    }
    else if(k==3){
        scanf("%d%d",&x,&z);
        change(1,1,n,tid[x],tid[e[x]],z);
    }
    else{
        scanf("%d",&x);
        printf("%d\n",query(1,1,n,tid[x],tid[e[x]]));
    }
   }
   return 0;
}

树链剖分

7.treap

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
const int maxn=100050;
int root,T,qs,xx,tot,v[maxn],l[maxn],r[maxn],hr[maxn],sz[maxn];
using namespace std;
void update(int x) {sz[x]=sz[l[x]]+sz[r[x]]+1;}
inline int read(){
    int ret=0,f=1;char ch=getchar();
    while(ch!=‘-‘&&ch<‘0‘||ch>‘9‘) ch=getchar();
    if(ch==‘-‘) f=-1,ch=getchar();
    for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) ret=ret*10+ch-‘0‘;
    return ret*f;
}
void left(int &x){
    int y=r[x];
    r[x]=l[y];
    l[y]=x;
    update(x);
    x=y;
    update(x);
}
void right(int &x){
    int y=l[x];
    l[x]=r[y];
    r[y]=x;
    update(x);
    x=y;
    update(x);
}
void del(int &y,int x){
    if(!y) return;
    if(v[y]==x){
    if(!l[y]) y=r[y];
    else if(!r[y]) y=l[y];
    else{
       if(hr[l[y]]<hr[r[y]]){
        right(y); del(r[y],x);
       }
       else{
            left(y); del(l[y],x);
       }
       update(y);
    }
    }
    else {
        if(x<v[y]) del(l[y],x);
        else del(r[y],x);
        update(y);
    }
}
int insert(int &y,int x)
{
    if(!y) {
        v[y=++tot]=x;
        hr[y]=rand();
        l[y]=0;r[y]=0;
    }
    else if(v[y]>x){
        insert(l[y],x);
        if(hr[l[y]]<hr[y]) right(y);
    }
    else {
        insert(r[y],x);
        if(hr[r[y]]<hr[y])  left(y);
        }
    update(y);
}
int rank(int y,int x){
   int res=1;
   for(;y;){
     if(v[y]<x) res+=sz[l[y]]+1,y=r[y];
     else y=l[y];
   }
   return res;
}
int kth(int y,int x){
    for(;y;){
        if(sz[l[y]]+1==x) return v[y];
        else if(sz[l[y]]+1<x) x-=(sz[l[y]]+1),y=r[y];
        else y=l[y];
    }
    return -1;
}
int pre(int x){
    int res=-1;
    for(int y=root;y;){
        if(v[y]<x) res=v[y],y=r[y];
        else y=l[y];
    }
    return res;
}
int nxt(int x){
    int res=-1;
    for(int y=root;y;){
        if(v[y]>x) res=v[y],y=l[y];
        else y=r[y];
    }
    return res;
}
int main()
{
   scanf("%d",&T);
   srand(time(0));
   while(T--){
     scanf("%d%d",&qs,&xx);
     switch(qs){
         case 1:insert(root,xx);break;
         case 2:del(root,xx);break;
         case 3:printf("%d\n",rank(root,xx));break;
         case 4:printf("%d\n",kth(root,xx));break;
         case 5:printf("%d\n",pre(xx));break;
         case 6:printf("%d\n",nxt(xx));break;
     }
   }
   return 0;
}

treap

8.splay

//Twenty
#include <cstdio>
#define Maxn 1000000
using namespace std;
int f[Maxn];
int ch[Maxn][2];
int key[Maxn];
int cnt[Maxn];
int siz[Maxn];
int sz,root;
void clear(int x) {
    ch[x][0]=ch[x][1]=f[x]=cnt[x]=key[x]=siz[x]=0;
}
int getson(int x) {return ch[f[x]][1]==x;}
void update(int x) {
    siz[x]=cnt[x];
    if (ch[x][0]) siz[x]+=siz[ch[x][0]];
    if (ch[x][1]) siz[x]+=siz[ch[x][1]];
}
int rotate(int x) {
    int fa=f[x],fafa=f[fa],k=getson(x);
    ch[fa][k]=ch[x][k^1];f[ch[fa][k]]=fa;
    ch[x][k^1]=fa;f[fa]=x;f[x]=fafa;
    if (fafa)
        ch[fafa][ch[fafa][1]==fa]=x;
    update(fa);update(x);
}
void splay(int x) {
    for (int fa;fa=f[x];rotate(x))
        if (f[fa])
            rotate(getson(x)==getson(fa) ? fa : x);
    root=x;
}
int pre() {
    int now=ch[root][0];
    while(ch[now][1])
        now=ch[now][1];
    return now;
}
int nex() {
    int now=ch[root][1];
    while(ch[now][0])
        now=ch[now][0];
    return now;
}
int findpos(int v) {
    int now=root,ans=0;
    while(1) {
        if (v<key[now])
            now=ch[now][0];
        else {
            ans+=ch[now][0]?siz[ch[now][0]]:0;
            if (v==key[now]) {
                splay(now);
                return ans+1;
            }
            ans+=cnt[now];
            now=ch[now][1];
        }
    }
}
int findx(int x) {
    int now=root;
    while(1) {
        if (ch[now][0] && x<=siz[ch[now][0]])
            now=ch[now][0];
        else {
            int temp=(ch[now][0]?siz[ch[now][0]]:0)+cnt[now];
            if (x<=temp)
                return key[now];
            x-=temp;
            now=ch[now][1];
        }
    }
}
void create(int v) {
    sz++;
    ch[sz][0]=ch[sz][1]=f[sz]=0;
    key[sz]=v;
    cnt[sz]=1;
    siz[sz]=1;
}
void insert(int v) {
    if (!root)
        create(v),root=sz;
    else {
        int now=root,fa=0;
        while(1) {
            if (key[now]==v) {
                cnt[now]++;
                splay(now);
                break;
            }
            fa=now;
            now=ch[fa][v>key[fa]];
            if (!now) {
                create(v);
                f[sz]=fa;
                ch[fa][v>key[fa]]=sz;
                update(fa);
                splay(sz);
                break;
            }
        }
    }
}
void del(int x) {
    int t=findpos(x);
    if (cnt[root]>1) {
        cnt[root]--;
        update(root);
        return;
    }
    if (!ch[root][0] && !ch[root][1]) {
        clear(root);
        root=0;
        return;
    }
    if (!ch[root][1]) {
        int temp=root;
        root=ch[root][0];
        f[root]=0;
        clear(temp);
        return;
    }
    else
    if (!ch[root][0]) {
        int temp=root;
        root=ch[root][1];
        f[root]=0;
        clear(temp);
        return;
    }
    int pre1=pre(),temp=root;
    splay(pre1);
    f[ch[temp][1]]=root;
    ch[root][1]=ch[temp][1];
    clear(temp);
    update(root);
}
int main()
{
    int n,opt,x;
    scanf("%d",&n);
    for (int i=1;i<=n;++i) {
        scanf("%d%d",&opt,&x);
        switch(opt) {
            case 1: insert(x); break;
            case 2: del(x); break;
            case 3: printf("%d\n",findpos(x)); break;
            case 4: printf("%d\n",findx(x)); break;
            case 5: insert(x); printf("%d\n",key[pre()]); del(x); break;
            case 6: insert(x); printf("%d\n",key[nex()]); del(x); break;
        }
    }
}   

splay

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#define lc ch[x][0]
#define rc ch[x][1]
using namespace std;
const int maxn=100005;
int n,T,l,r,root,cnt,flip[maxn],ch[maxn][2],p[maxn],sz[maxn];
void update(int x) {sz[x]=sz[lc]+sz[rc]+1;}
void down(int x){
    if(!flip[x]) return;
    swap(lc,rc);
    flip[lc]^=1;flip[rc]^=1;
    flip[x]=0;
}
int kth(int x,int a){
    for(;x;){
    down(x);
    int k=sz[lc]+1;
    if(k==a) return x;
    if(k<a) a-=k,x=rc;
    else x=lc;
    }
}
void rotate(int x){
     int y=p[x],z=p[y];
     if(z) ch[z][y==ch[z][1]]=x; p[x]=z;
     l=(x==ch[y][1]),r=l^1;
     ch[y][l]=ch[x][r]; p[ch[y][l]]=y;
     ch[x][r]=y; p[y]=x;
     update(y);
     update(x);
}
void splay(int x,int FA){
    if(p[x]!=FA){
        static int s[maxn],top=0;
      for(int i=x;i;i=p[i]) s[++top]=i;
      while(top) down(s[top--]);
    }
    for(;p[x]!=FA;rotate(x)){
       int y=p[x],z=p[y];
       if(z!=FA){
           ((ch[z][1]==y)^(ch[y][1]==x))?rotate(x):rotate(y);
       }
    }
    if(!FA) root=x;
}
void rever(int l,int r){
    l=kth(root,l);r=kth(root,r+2);
    splay(l,0);
    splay(r,l);
    int x=ch[root][1];
    flip[lc]^=1;
    int now=ch[r][0];
    ch[r][0]=0;
    update(r);
    update(root);
    x=kth(root,n-sz[now]+1);
    splay(x,0);
    x=rc; lc=now; update(x); update(root);
}
int build(int n){
    if(!n) return 0;
    l=build(n>>1);
    int x=++cnt;
    lc=l;
    r=build(n-(n>>1)-1);
    rc=r;
    if(lc) p[lc]=x;
    if(rc) p[rc]=x;
    update(x);
    return x;
}
void print(int x){
    if(!x) return;
    down(x);
    print(lc);
    if(x>=2&&x<=n+1) printf("%d ",x-1);
    print(rc);
}
int main()
{
   scanf("%d%d",&n,&T);
   root=build(n+2);
   while(T--){
        scanf("%d%d",&l,&r);
        rever(l,r);
   }
   print(root);
   return 0;
}

文艺平衡树

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#define lc ch[x][0]
#define rc ch[x][1]
using namespace std;
const int maxn=100005;
int aa,bb,tot,root,n,m,ch[maxn][2],p[maxn],flip[maxn],sz[maxn];
void update(int x) {sz[x]=sz[lc]+sz[rc]+1;}
void down(int x){
  if(!flip[x]) return;
  swap(lc,rc);
  flip[x]^=1;
  flip[lc]^=1;
  flip[rc]^=1;
}
void rotate(int x){
    int y=p[x],z=p[y],l=(x==ch[y][1]),r=l^1;
    if(z) ch[z][y==ch[z][1]]=x; p[x]=z;
    ch[y][l]=ch[x][r]; p[ch[y][l]]=y;
    ch[x][r]=y; p[y]=x;
    update(y); update(x);
}
void splay(int x,int FA){
   if(p[x]==FA) return;
   static int s[maxn],top;
   for(int i=x;i;i=p[i]) s[++top]=i;
   while(top) down(s[top--]);
   for(;p[x]!=FA;rotate(x)){
     int y=p[x],z=p[y];
     if(z!=FA){
       ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y);
     }
   }
   if(FA==0) root=x;
}
int build(int n){
   if(!n) return 0;
   int ll=build(n>>1);
   int x=++tot;
   lc=ll;
   rc=build(n-(n>>1)-1);
   if(lc) p[lc]=x;
   if(rc) p[rc]=x;
   update(x);
   return x;
}
int kth(int k){
    for(int x=root;x;){
       down(x);
       if(sz[lc]+1==k) return x;
       if(sz[lc]+1<k) k-=(sz[lc]+1),x=rc;
       else x=lc;
    }
}
void print(int x){
  if(!x) return;
  down(x);
  print(lc);
  if(x>1&&x<n+2) printf("%d\n",x-1);
  print(rc);
}
void rever(int l,int r){
    int ll=kth(l),rr=kth(r+2);
    //print(root);
    splay(ll,0); splay(rr,ll);
    flip[ch[rr][0]]^=1;
    int now=ch[rr][0];
    ch[rr][0]=0;
    update(rr);
    update(root);
    int x=kth(n-sz[now]+1);
    splay(x,0);
    x=rc; lc=now; p[now]=x; update(x); update(root);
}

int main()
{
   scanf("%d%d",&n,&m);
   root=build(n+2);
   while(m--){
    scanf("%d%d",&aa,&bb);
    rever(aa,bb);
   }
   print(root);
   return 0;
}

文艺平衡树加强

9.LCT

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#define lc ch[x][0]
#define rc ch[x][1]
const int maxn=3*1e5+5;
using namespace std;
int k,tot,n,m,a,b,p[maxn],ch[maxn][2],v[maxn],sum[maxn],flip[maxn];
inline int read(){
  int ret=0,f=1; char ch=getchar();
  while((ch!=‘-‘)&&(ch<‘0‘||ch>‘9‘)) ch=getchar();
  if(ch==‘-‘) f=-1,ch=getchar();
  for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) ret=ret*10+ch-‘0‘;
  return ret*f;
}
void update(int x) {sum[x]=v[x]; if(lc)sum[x]^=sum[lc]; if(rc)sum[x]^=sum[rc];}
void down(int x){
    if(!flip[x]) return ;
    swap(lc,rc);
    flip[lc]^=1;
    flip[rc]^=1;
    flip[x]^=1;
}
bool isroot(int x) {return (ch[p[x]][0]!=x)&&(ch[p[x]][1]!=x);}
void rotate(int x){
    int y=p[x],z=p[y],l=(x==ch[y][1]),r=l^1;
    if(!isroot(y)) ch[z][y==ch[z][1]]=x; p[x]=z;
    ch[y][l]=ch[x][r]; p[ch[x][r]]=y;
    ch[x][r]=y; p[y]=x;
    update(y); update(x);
}
void splay(int x){
    static int s[maxn],top;
    s[top=1]=x;
    for(int i=x;!isroot(i);i=p[i]) s[++top]=p[i];
    while(top) down(s[top--]);
    for(;!isroot(x);rotate(x)){
        int y=p[x],z=p[y];
        if(!isroot(y)){
         ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y);
        }
    }
}
void access(int x){
    for(int t=0;x;x=p[t=x]){
     splay(x);
     ch[x][1]=t;
     update(x);
    }
}
int findroot(int x){
  access(x);
  splay(x);
  while(lc) x=lc;
  return x;
}
bool lt(int a,int b){
  return findroot(a)==findroot(b);
}
void newroot(int x){
   access(x);
   splay(x);//fasdgggggggggggggggg
   flip[x]^=1;
}
void link(int a,int b){
    if(lt(a,b)) return;
    newroot(a);
    p[a]=b;
}
void del(int a,int b){
   newroot(a);//splay(a);
   access(b);
   //if(p[b]==a) ch[a][b==ch[a][1]]=0;
   splay(b);//sdgadfffgaggggggggggfjdgfjhfghgf
   if(ch[b][0]==a) ch[b][0]=p[a]=0;
}
void change(int a,int b){
   splay(a);//newroot(a);
   v[a]=b;
   update(a);
}
void query(int a,int b){
  newroot(a);//splay(a);
  access(b);
  splay(b);//gdfgfgb gshfthhhhhhhhhhhhhhhhhhhhh
  printf("%d\n",sum[b]);
}
int main()
{
   n=read(); m=read();
   for(int i=1;i<=n;i++){
    a=read();
    v[i]=sum[i]=a;
   }
   while(m--){
    k=read(); a=read(); b=read();
    switch(k){
    case 0:query(a,b);break;
    case 1:link(a,b); break;
    case 2:del(a,b); break;
    case 3:change(a,b);break;
    }
   }
   return 0;
}

LCT

10.左偏树

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#define lc ch[x][0]
#define rc ch[x][1]
const int maxn=100000+299;
using namespace std;
int n,m,k,x,y,ch[maxn][2],fa[maxn],v[maxn],bo[maxn],dis[maxn];
int find(int x){
    return x==fa[x]?x:fa[x]=find(fa[x]);
}
int merge(int x,int y){
    if(!x) {return y;}
    if(!y) {return x;}
    if(v[x]>v[y]) swap(x,y);
    fa[y]=x;
    rc=merge(rc,y);
    if(dis[rc]>dis[lc]) swap(lc,rc);
    if(!rc) dis[x]=0;
    else dis[x]=dis[rc]+1;
    return x;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&v[i]);
        fa[i]=i;
    }
    while(m--){
        scanf("%d%d",&k,&x);
        if(k==1){
        scanf("%d",&y);
            if(!bo[x]&&!bo[y]&&find(x)!=find(y))
            x=merge(find(x),find(y));
        }
        else{
            if(bo[x]) cout<<-1<<endl;
            else{
            x=find(x);
            printf("%d\n",v[x]);
            fa[lc]=lc; fa[rc]=rc;
            if(lc&&rc) lc=merge(lc,rc);
            if(lc) fa[x]=lc;
            else fa[x]=rc;
            lc=rc=0;
            }
            bo[x]=1;
        }
    }
    return 0;
}

左偏树

11.KD-Tree

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=500000+299;
using namespace std;
int ans=1e9+7,now,nowx,nowmax,nowmin,root,y,n,D,data[maxn][2][2],ch[maxn][2];
struct node{
    int d[2];
    friend bool operator <(const node&A,const node&B){
        return A.d[D]<B.d[D];
    }
}a[maxn],T;
void update(int x){
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            data[x][i][j]=a[x].d[i];
    for(int i=0;i<2;i++)
       if(y=ch[x][i])
       for(int j=0;j<2;j++){
           data[x][j][0]=min(data[x][j][0],data[y][j][0]);
           data[x][j][1]=max(data[x][j][1],data[y][j][1]);
       }
}
int build(int l,int r,int k){
    if(l>r) return 0;
    int mid=(l+r)>>1;
    D=k;
    nth_element(a+l,a+mid,a+r+1);
    ch[mid][0]=build(l,mid-1,k^1);
    ch[mid][1]=build(mid+1,r,k^1);
    update(mid);
    return mid;
}
int max_dis(int x){
    if(!x) return -1e9;
    int res=0;
    for(int i=0;i<2;i++)
        res+=max(abs(T.d[i]-data[x][i][0]),abs(data[x][i][1]-T.d[i]));
    return res;
}
int dis(int x){
    return abs(a[x].d[0]-T.d[0])+abs(a[x].d[1]-T.d[1]);
}
int min_dis(int x){
    if(!x) return 1e9;
    int res=0;
    for(int i=0;i<2;i++)
    res+=max(T.d[i]-data[x][i][1],0);
    for(int i=0;i<2;i++)
    res+=max(data[x][i][0]-T.d[i],0);
    return res;
}
void qrymin(int x){
    if(!x) return;
    if(x!=nowx) nowmin=min(dis(x),nowmin);
    int lc=ch[x][0],rc=ch[x][1];
    int l=min_dis(lc);
    int r=min_dis(rc);
    if(l>r) {swap(lc,rc);swap(l,r);}
    if(lc&&l<nowmin) qrymin(lc);
    if(rc&&r<nowmin) qrymin(rc);
}
void qrymax(int x){
    if(!x) return;
    if(x!=nowx) nowmax=max(dis(x),nowmax);
    int lc=ch[x][0],rc=ch[x][1];
    int l=max_dis(lc);
    int r=max_dis(rc);
    if(l<r) {swap(lc,rc);swap(l,r);}
    if(lc&&l>nowmax) qrymax(lc);
    if(rc&&r>nowmax) qrymax(rc);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d%d",&a[i].d[0],&a[i].d[1]);
    root=build(1,n,0);
    for(int i=1;i<=n;i++){
        nowx=i;
        T=a[i];
        nowmax=-1e9+7;
        nowmin=1e9+7;
        qrymin(root);
        qrymax(root);
        ans=min(ans,nowmax-nowmin);
    }
    printf("%d\n",ans);
   return 0;
}

KD-Tree

12.

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#define lc x<<1
#define rc x<<1|1
#define mid ((l+r)>>1)
const int maxn=10005;
bool st;
int tot,T,ql,qr,qq,aa[maxn],n,m,sg[maxn<<2],ls[maxn*450],rs[maxn*450],sgq[maxn*450],que[maxn];
int nn=1e9;
char qs[5];
bool ed;
using namespace std;
inline int read() {
 int res=0;char ch=getchar();
 while(ch<‘0‘||ch>‘9‘) ch=getchar();
 for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) res=res*10+ch-‘0‘;
 return res;
}
void buq(int &x,int l,int r,int v,int kk){
    if(!x) x=++tot;
    if(l==r) {if(kk) sgq[x]++; else sgq[x]--; return;}
    if(v<=mid) buq(ls[x],l,mid,v,kk);
    else buq(rs[x],mid+1,r,v,kk);
    sgq[x]=sgq[ls[x]]+sgq[rs[x]];
}
void build(int x,int l,int r){
    for(int i=l;i<=r;i++) buq(sg[x],1,nn,aa[i],1);
    if(l==r) return;
    build(lc,l,mid); build(rc,mid+1,r);
}
void change(int x,int l,int r,int xw,int jv,int xv){
    buq(sg[x],1,nn,jv,0); buq(sg[x],1,nn,xv,1);
    if(l==r) return;
    if(xw<=mid) change(lc,l,mid,xw,jv,xv);
    else change(rc,mid+1,r,xw,jv,xv);
}
void query(int x,int l,int r,int ql,int qr){
    if(l>=ql&&r<=qr) {que[++que[0]]=sg[x];return;}
    if(qr<=mid) query(lc,l,mid,ql,qr);
    else if(ql>mid) query(rc,mid+1,r,ql,qr);
    else {query(lc,l,mid,ql,qr); query(rc,mid+1,r,ql,qr);}
}
int qry(int ql,int qr,int k){
    que[0]=0;
    query(1,1,n,ql,qr);
    int l=1,r=nn;
    for(;;){
        int now=0;
        for(int i=1;i<=que[0];i++)
        now+=sgq[ls[que[i]]];
        if(now>=k) {
         for(int i=1;i<=que[0];i++)
          que[i]=ls[que[i]];
         r=mid;
        }
        else{
         for(int i=1;i<=que[0];i++)
          que[i]=rs[que[i]];
         k-=now;
         l=mid+1;
        }
        if(l==r) return l;
    }
}
int main()
{
    //printf("%d\n",(&ed-&st)/1024/1024);
    //for(;;);
   //freopen("dynamic9.in","r",stdin);
   //freopen("aa.out","w",stdout);
   /*scanf("%d",&T);
   while(T--){*/
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) {aa[i]=read(); aa[i]++; }
    /*sort(aa+1,aa+n+1);
    nn=unique(aa+1,aa+n+1)-(aa+1);*/
    //for(int i=1;i<=n;i++) {bb[i]=lower_bound(aa+1,aa+n+1,bb[i])-aa;}
    build(1,1,n);
    while(m--){
      scanf("%s",qs);
       ql=read(); qr=read();
      if(qs[0]==‘C‘){
           qr++;
         change(1,1,n,ql,aa[ql],qr);
         aa[ql]=qr;
      }
      else{
        qq=read();//scanf("%d",&qq);
        printf("%d\n",qry(ql,qr,qq)-1);
      }
    }
    /*if(T){
    tot=0;
    memset(aa,0,sizeof(aa));
    memset(sg,0,sizeof(sg));
    memset(sgq,0,sizeof(sgq));
    memset(ls,0,sizeof(ls));
    memset(rs,0,sizeof(rs));
    }
   }*/
   return 0;
}

树套树

时间: 2025-01-31 20:16:26

高级数据结构模板的相关文章

Python中的高级数据结构

数据结构 数据结构的概念很好理解,就是用来将数据组织在一起的结构.换句话说,数据结构是用来存储一系列关联数据的东西.在Python中有四种内建的数据结构,分别是List.Tuple.Dictionary以及Set.大部分的应用程序不需要其他类型的数据结构,但若是真需要也有很多高级数据结构可供选择,例如Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint.本文将介绍这些数据结构的用法,看看它们是如何帮助我们的应用程序的. 关于四种内建数据结构的使用方

高级数据结构实现——自顶向下伸展树

[0]README 1) 本文部分内容转自 数据结构与算法分析,旨在理解 高级数据结构实现——自顶向下伸展树 的基础知识: 2) 源代码部分思想借鉴了数据结构与算法分析,有一点干货原创代码,for original source code, please visithttps://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter12/p345_topdown_splay_tree 3) you c

Python中的高级数据结构(转)

add by zhj: Python中的高级数据结构 数据结构 数据结构的概念很好理解,就是用来将数据组织在一起的结构.换句话说,数据结构是用来存储一系列关联数据的东西.在Python中有四种内建的数据 结构,分别是List.Tuple.Dictionary以及Set.大部分的应用程序不需要其他类型的数据结构,但若是真需要也有很多高级数据结构可供 选择,例如Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint.本文将介绍这些数据结构的用法,看 看它

Python中的高级数据结构详解

这篇文章主要介绍了Python中的高级数据结构详解,本文讲解了Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint这些数据结构的用法,需要的朋友可以参考下 数据结构 数据结构的概念很好理解,就是用来将数据组织在一起的结构.换句话说,数据结构是用来存储一系列关联数据的东西.在Python中有四种内建的数据结构,分别是List.Tuple.Dictionary以及Set.大部分的应用程序不需要其他类型的数据结构,但若是真需要也有很多高级数据结构可供选择

高级数据结构

数据结构清单 Binomial Heap Leftist Tree:左倾堆 ? 重型网络教程 1.纸上谈兵:算法与数据结构 2.CS 598 JGE:Advanced Data Structures(Fall 2015) 3.COP 5536 Advanced Data Structures(Florida) 4.wikibooks Data Structures 5.Geeksforgeeks(very much) 6.COMP 5408:Advanced Data Struestures 7

GO语言的进阶之路-Golang高级数据结构定义

GO语言的进阶之路-Golang高级数据结构定义 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们之前学习过Golang的基本数据类型,字符串和byte,以及rune也有所了解,但是说起高级点的数据类型,可能我们还是不太清楚,那么今天就跟着我脚步一起学习一下这些高级数据类型数据吧.相信有部分人可能学习过Python,那么我这篇博客基本上不用看了,因为对你来说会觉得so easy.因为太多的相似之处了,只是写法不同.本章主要介绍数组(array),切片(scice),字典(m

二叉图(高级数据结构)

一.定义 二叉图(Binary-Map),一种C++14规范中引入的高级数据结构.其集合了二叉树和图论的优点,在世界算法数据结构大会上由斯茂·斯迪尤德恩特首先提出.  二叉图在形式上类似于二叉树,其实现类似于图论(在下面的代码中有介绍).由N个点,E条边构成,E在等于N-1时二叉图的复杂度退化为二叉树,其主要特征是二叉图的深度为depth以下的点中可以以图的方式两两连接,并忽略其中边权,直接理解为两点重合,从而达到以二叉形式实现连通环的目的.  其形式近似于完全连通的杨辉三角或子节点重合的完全二

Python高级数据结构(一)

数据结构 数据结构的概念很好理解,就是用来将数据组织在一起的结构.换句话说,数据结构是用来存储一系列关联数据的东西.在Python中有四种内建的数据结构,分别是List.Tuple.Dictionary以及Set.大部分的应用程序不需要其他类型的数据结构,但若是真需要也有很多高级数据结构可供选择,例如Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint.本文将介绍这些数据结构的用法,看看它们是如何帮助我们的应用程序的. 关于四种内建数据结构的使用方

高级数据结构:优先队列、图、前缀树、分段树以及树状数组详解

优秀的算法往往取决于你采用哪种数据结构,除了常规数据结构,日常更多也会遇到高级的数据结构,实现要比那些常用的数据结构要复杂得多,这些高级的数据结构能够让你在处理一些复杂问题的过程中多拥有一把利器.同时,掌握好它们的性质以及所适用的场合,在分析问题的时候回归本质,很多题目都能迎刃而解了. 这篇文章将重点介绍几种高级的数据结构,它们是:优先队列.图.前缀树.分段树以及树状数组. 一.优先队列 1.优先队列的作用 优先队列最大的作用是能保证每次取出的元素都是队列中优先级别最高的,这个优先级别可以是自定