【テンプレート】初级数据结构
1.链表
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 200; const int M = 10000; int n,m,num,ans=-1,p; struct node { int next,to,w; }e[M<<1]; int top,head[N]; void add(int u,int v,int w) { e[top].to=v; e[top].w=w; e[top].next=head[u]; head[u]=top++; } void dfs(int u) { num=0; printf("u=%d\n",u); for(int i=head[u],v,w; i!=-1; i=e[i].next) { num++; v=e[i].to,w=e[i].w; printf("%d %d\n",v,w); } printf("num=%d\n",num); if(num>ans) ans=num,p=u; } int main() { memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(int i=0,u,v,w; i<m; i++) { scanf("%d%d%d",&u,&v,&w); add(u,v,w),add(v,u,w); } for(int i=1; i<=n; i++) dfs(i); printf("%d %d",p,ans); return 0; } /* 8 10 5 2 1 1 3 5 4 8 6 2 3 3 5 8 9 3 4 7 2 7 11 7 6 3 6 1 2 3 6 8 */
2.双向链表
3.队列
#include <iostream> #include <queue> using namespace std; int main() { queue <int> q; while(!q.empty() || q.size()>0) q.pop(); int x; cin>>x; q.push(x); int p=q.front(); cout<<p; return 0; }
4.单调队列(eg:滑动窗口)
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N = 1e6 + 5; int n,k,l,r; int a[N],q[N],p[N]; int main() { scanf("%d%d",&n,&k); for(int i=1; i<=n; i++) scanf("%d",&a[i]); for(int i=1; i<=n; i++) { if(q[l]<=i-k) l++; while(l<=r && a[i]<=a[q[r]]) r--; //单调递增 q[++r]=i; p[i]=a[q[l]]; } for(int i=k; i<=n; i++) printf("%d ",p[i]); printf("\n"); memset(p,0,sizeof(p)); l=0,r=0; for(int i=1; i<=n; i++) { if(q[l]<=i-k) l++; while(l<=r && a[i]>=a[q[r]]) r--; //单调递减 q[++r]=i; p[i]=a[q[l]]; } for(int i=k; i<=n; i++) printf("%d ",p[i]); return 0; }
5.双端队列(eg:牛线Cow Line) 使用STL:duque
#include <iostream> #include <cstdio> #include <deque> using namespace std; const int N = 100001; int n; deque<int>q; char a,b; int main() { scanf("%d",&n); for(int i=1,k,now=1; i<=n; i++) { cin>>a>>b; if(a=='A') { if(b=='L') q.push_front(now++); else q.push_back(now++); } else { scanf("%d",&k); for(int j=1; j<=k; j++) if(b=='L') q.pop_front(); else q.pop_back(); } } while(!q.empty()) { printf("%d\n",q.front()); q.pop_front(); } return 0; }
6.栈(eg:车厢调度)
#include <iostream> #include <cstdio> using namespace std; int n,top=0,a[1010],b[1010]; int main() { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&a[i]); for(int i=1,cur=1; i<=n; i++) { while(b[top]<a[i]) b[++top]=cur++; if(b[top]==a[i]) top--; else { printf("NO\n"); return 0; } } printf("YES\n"); return 0; }
7.单调栈(eg:财富(treasure))
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define LL long long using namespace std; const int M = 50055; int n,qt,a[M]; LL h[M],q1[M],q2[M],ans[M]; bool visq[M]; int main() { freopen("treasure.in","r",stdin); freopen("treasure.out","w",stdout); scanf("%d",&n); for(int i=1; i<=n; ++i) { scanf("%d%d",&h[i],&a[i]); while(qt>0 && h[i]>q1[qt]) { //right if(!visq[q2[qt]]) { ans[i]+=a[q2[qt]]; visq[q2[qt]]=true; } qt--; } q1[++qt]=h[i]; q2[qt]=i; } qt=0; memset(visq,0,sizeof(visq)); memset(q1,0,sizeof(q1)); memset(q2,0,sizeof(q2)); for(int i=n; i>=1; --i) { //left while(qt>0 && h[i]>q1[qt]) { //right if(!visq[q2[qt]]) { ans[i]+=a[q2[qt]]; visq[q2[qt]]=true; } qt--; } q1[++qt]=h[i]; q2[qt]=i; } sort(ans+1,ans+n+1); printf("%d",ans[n]); return 0; } My
8.堆
#include <iostream> #include <cmath> using namespace std; const int N = 1000010; int n,len; int d[N<<1]; void add(int x) { int now,next; d[++len]=x; now=len; while(now>1) { next=now>>1; if(d[now]>=d[next]) break; swap(d[now],d[next]); now=next; } } void print() { cout<<d[1]<<endl; } void del() { int now,next,root; root=d[1]; d[1]=d[len--]; now=1; while((now<<1)<=len) { next=now<<1; if(next<len && d[next+1]<d[next]) next++; if(d[now]<=d[next]) return; swap(d[now],d[next]); now=next; } } int main() { cin.sync_with_stdio(false); cin>>n; for(int i=1,c; i<=n; i++) { cin>>c; if(c==1) { int q; cin>>q; add(q); } else if(c==2) print(); else del(); } return 0; }