【模板整合计划】基础数据结构
【模板整合计划】基础数据结构
一:【栈】
1.【对顶栈】
#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.【单调队列】
#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]);
}
}
三:【链表】
#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]}\)
#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);
}