【模板整合计划】基础数据结构

【模板整合计划】基础数据结构


一:【栈】

1.【对顶栈】

\(\text{Editor [HDU4699]}\)

#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e6+5;
int m,x,tl,tr,L[N],R[N],f[N],s[N];char a;
int main(){
    while(scanf("%d",&m)!=EOF){
        s[0]=0;f[0]=-0xfffffff;tl=tr=0;
        while(m--){
            cin>>a;
            if(a=='I'){
                scanf("%d",&x);
                L[++tl]=x;
                f[tl]=max(f[tl-1],s[tl]=s[tl-1]+x);
            }
            else if(a=='R'){
                if(tr){
                    x=L[++tl]=R[tr--];
                    f[tl]=max(f[tl-1],s[tl]=s[tl-1]+x);
                }
            }
            else if(a=='Q')scanf("%d",&x),printf("%d\n",f[x]);
            else if(a=='L'){if(tl)R[++tr]=L[tl--];}
            else if(tl)tl--;
        }
    }
}

2.【单调栈】

\(\text{Largest Rectangle in a Histogram [SP1805]}\)

#include<algorithm>
#include<cstdio>
int i,n,t,wi,a[100005],Q[100005],W[100005];
long long ans;
int main(){
    while(scanf("%d",&n)!=EOF){
        if(!n)break;
        for(i=1;i<=n;i++)scanf("%d",&a[i]);
        ans=a[n+1]=t=0;
        for(i=1;i<=n+1;i++)
            if(a[i]>Q[t])Q[++t]=a[i],W[t]=1;
            else{
                wi=0;
                while(t&&a[i]<=Q[t])ans=std::max(ans,(long long)(wi+=W[t])*Q[t--]);
                Q[++t]=a[i],W[t]=wi+1;
            }
        printf("%lld\n",ans);
    }
}

3.【表达式求值】

【模板】表达式计算 \(4\) \(\text{[CH1802]}\)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#define LL long long
using namespace std;
int n,f,t1,t2,i,power[300],ch[40];
LL x,sum[40];string a;
LL mi(LL x,LL k){
    LL s=1;
    while(k){
        if(k&1)s=(s*x);
        x=(x*x);k>>=1;
    }
    return s;
}
inline void pop(char fh){
    t1--;t2--;
    if(fh=='+')sum[t1]+=sum[t1+1];
    if(fh=='-')sum[t1]-=sum[t1+1];
    if(fh=='*')sum[t1]*=sum[t1+1];
    if(fh=='/')sum[t1]/=sum[t1+1];
    if(fh=='^')sum[t1]=mi(sum[t1],sum[t1+1]);
}
int main(){
    cin>>a;a='('+a+')';n=a.size();
    power['(']=0;power['+']=power['-']=1;power['*']=power['/']=2;power['^']=3;
    while(i<n){
        x=0,f=0;
        while(isdigit(a[i]))x=x*10+a[i++]-'0',f=1;
        if(f)sum[++t1]=x;
        if(a[i]=='(')ch[++t2]=a[i++];
        if(a[i]==')'){
            while(ch[t2]!='(')pop(ch[t2]);
            i++;t2--;
        }
        if(power[a[i]]){
            if(a[i]=='-'&&a[i-1]=='('){
                x=0,i++;
                while(isdigit(a[i]))x=x*10+a[i++]-'0';
                sum[++t1]=-x;
            }
            else {
                while(power[a[i]]<=power[ch[t2]])pop(ch[t2]);
                ch[++t2]=a[i++];
            }
        }
    }
    while(t2)pop(ch[t2]);
    printf("%lld",sum[1]);
}

二:【队列】

1.【单调队列】

【模板】单调队列 / 滑动窗口 \([P1886]\)

#include<algorithm>
#include<cstdio>
const int N=1e6+5;
int n,k,i,h,t,a[N],Q[N],D[N];
int main(){
    scanf("%d%d",&n,&k);
    for(i=1;i<=n;i++){
        scanf("%d",&a[i]);
        while(h<=t&&Q[t]>=a[i])t--;Q[++t]=a[i],D[t]=i;
        while(h<t&&D[h]+k-1<i)h++;
        if(i>=k)printf("%d ",Q[h]);
    }
    printf("\n");h=t=0;
    for(i=1;i<=n;i++){
        while(h<=t&&Q[t]<=a[i])t--;Q[++t]=a[i],D[t]=i;
        while(h<t&&D[h]+k-1<i)h++;
        if(i>=k)printf("%d ",Q[h]);
    }
}

三:【链表】

队列安排 \(\text{[P1160]}\)

#include<cstdio>
#define Re register int
const int N=1e5+3;
int n,x,T,op,vis[N],pre[N],nex[N];
inline void in(Re &x){
    int f=0;x=0;char c=getchar();
    while(c<'0'||c>'9')f|=c=='-',c=getchar();
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    x=f?-x:x;
}
int main(){
    in(n),nex[0]=1,pre[n+1]=1,pre[1]=0,nex[1]=n+1;
    for(Re i=2;i<=n;++i){
        in(x),in(op);
        if(op)nex[i]=nex[x],pre[nex[x]]=i,nex[pre[i]=x]=i;
        else pre[i]=pre[x],nex[pre[x]]=i,pre[nex[i]=x]=i;
    }
    in(T);while(T--){
        in(x);if(vis[x])continue;vis[x]=1;
        nex[pre[x]]=nex[x],pre[nex[x]]=pre[x];
    }
    for(Re i=nex[0];i<=n;i=nex[i])printf("%d ",i);
}

四:【二叉堆】

1.【手写 Heap】

\(\text{Supermarket [POJ1456]}\)

【模板】堆 \(\text{[P3378]}\)

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
struct QAQ{int w,d;}a[10003];
int ans,n,i;
inline bool cmp(QAQ a,QAQ b){return a.d!=b.d?a.d<b.d:a.w>b.w;}
struct QWQ{
    int heap[10003],t;
    inline void CL(){memset(heap,0,sizeof(heap));t=0;}
    inline void up(int p){
        while(p>1)
            if(heap[p>>1]>heap[p])swap(heap[p],heap[p>>1]),p>>=1;
            else break;
    }
    inline void down(int p){
        int s=(p<<1);
        while(s<=t){
            if(s<t&&heap[s]>heap[s|1])s++;
            if(heap[s]<heap[p]){
                swap(heap[s],heap[p]);
                p=s,s<<=1;
            }
            else break;
        }
    }
    inline void pop(){delet(1);}
    inline int top(){return heap[1];}
    inline int size(){return t;}
    inline void push(int x){heap[++t]=x;up(t);}
    inline void delet(int p){swap(heap[p],heap[t--]);down(p);}
}Q;
int main(){
    while(scanf("%d",&n)!=EOF){
        for(i=1;i<=n;i++)scanf("%d%d",&a[i].w,&a[i].d);
        sort(a+1,a+n+1,cmp);ans=0;Q.CL();
        for(i=1;i<=n;i++)
            if(Q.size()<a[i].d)Q.push(a[i].w);
            else if(Q.top()<a[i].w)Q.pop(),Q.push(a[i].w);
        while(Q.size())ans+=Q.top(),Q.pop();
        printf("%d\n",ans);
    }
}

2.【Huffman】

荷马史诗 \(\text{[NOI2015] [P2168]}\)

#include<algorithm>
#include<cstdio>
#define LL long long
#define Re register LL
using namespace std;
LL ans,fu,S,d,k,n,t,i,x;
struct QAQ{LL x,d;inline bool operator<(QAQ b)const{return x==b.x?d<b.d:x<b.x;}}Q[100011];
inline void up(Re p){
    while(p>1)
        if(Q[p]<Q[p>>1])swap(Q[p],Q[p>>1]),p>>=1;
        else break;
}
inline void down(Re p){
    int s=p<<1;
    while(s<=t){
        if(s<t&&Q[s|1]<Q[s])s++;
        if(Q[s]<Q[p])swap(Q[s],Q[p]),p=s,s<<=1;
        else break;
    }
}
inline void push(Re x,Re d){Q[++t].x=x,Q[t].d=d;up(t);}
inline void delet(Re p){swap(Q[p],Q[t--]);down(p);}
inline void in(Re &x){
    x=fu=0;char c=getchar();
    while(c<'0'||c>'9')fu|=c=='-',c=getchar();
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    if(fu)x=-x;
}
int main(){
    in(n),in(k);
    while(n--)in(x),push(x,0);
    while((t-1)%(k-1))push(0,0);
    while(t>1){
        x=k,S=0,d=0;
        while(x--)d=max(d,Q[1].d),S+=Q[1].x,delet(1);
        ans+=S,push(S,d+1);
    }
    printf("%lld\n%lld",ans,Q[1].d);
}


-----若要转载请私信作者获得许可并在文首标出转载来源-----

posted @ 2019-05-28 21:21  辰星凌  阅读(433)  评论(1编辑  收藏  举报