NOIP 考前 数据结构复习

Posted yyjxx2010xyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIP 考前 数据结构复习相关的知识,希望对你有一定的参考价值。

BZOJ 1455 左偏树即可

 1 #include <cstdio>
 2 #define LL long long
 3 const LL Maxn=1000100;
 4 struct Info{LL l,r,v,Dis;}Tree[Maxn];
 5 LL Father[Maxn],n,m,Dead[Maxn],u,v;
 6 inline void Swap(LL &x,LL &y){LL t=x;x=y;y=t;}
 7 LL Get(LL x) {return x==Father[x]?x:Father[x]=Get(Father[x]);}
 8 LL Merge(LL u,LL v)
 9 {
10     if (u==0 || v==0) return u+v;
11     if (Tree[u].v>Tree[v].v) Swap(u,v);
12     Tree[u].r=Merge(Tree[u].r,v);
13     if (Tree[Tree[u].l].Dis<Tree[Tree[u].r].Dis) 
14         Swap(Tree[u].l,Tree[u].r);
15     Tree[u].Dis=Tree[Tree[u].l].Dis+1;
16     return u;
17 }
18 int main()
19 {
20     scanf("%lld",&n);
21     for (LL i=1;i<=n;i++) scanf("%lld",&Tree[i].v),Tree[i].l=Tree[i].r=0;
22     for (LL i=1;i<=n;i++) Father[i]=i;
23     scanf("%lld",&m);
24     for (LL i=1;i<=m;i++)
25     {
26         char ch=getchar();
27         while (ch!=\'M\' && ch!=\'K\') ch=getchar();
28         if (ch==\'M\')
29         {
30             scanf("%lld%lld",&u,&v);
31             LL fu=Get(u);
32             LL fv=Get(v);
33             if (fu==fv || Dead[u] || Dead[v]) continue;
34             LL Tmp=Merge(fu,fv);
35             Father[fu]=Father[fv]=Tmp;
36         } 
37         if (ch==\'K\')
38         {
39             scanf("%lld",&u);
40             if (Dead[u]) {puts("0"); continue;}
41             LL fu=Get(u); Dead[fu]=true;
42             printf("%lld\\n",Tree[fu].v);
43             LL Tmp=Merge(Tree[fu].l,Tree[fu].r);
44             Father[fu]=Tmp;
45             Father[Tmp]=Tmp;
46         }
47     }
48     return 0;
49 }
BZOJ 1455

 BZOJ 1803 用主席树维护Dfs序就可以了

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstring>
  4 #include <cstdio>
  5 using namespace std;
  6 const int Maxn=200010;
  7 const int Maxm=4010000;
  8 inline void Get_Int(int &x)
  9 {
 10     x=0; register char ch=getchar(); int f=1;
 11     while (ch<\'0\' || ch>\'9\') {if (ch==\'-\') f=-1; ch=getchar();}
 12     while (ch>=\'0\' && ch<=\'9\') {x=x*10+ch-\'0\'; ch=getchar();} x*=f;
 13 }
 14 inline void Put_Int(int x)
 15 {
 16     char ch[20]; register int top=0;
 17     if (x<0) putchar(\'-\'),x=-x;
 18     if (x==0) ch[++top]=\'0\';
 19     while (x) ch[++top]=x%10+\'0\',x/=10;
 20     while (top) putchar(ch[top--]); putchar(\'\\n\');
 21 }
 22 struct Node {int Sum; Node * l,* r;};
 23 Node Memory[Maxm],*port=Memory,* Root[Maxn],* null;
 24 inline void Init() {null=port++;null->Sum=0;null->l=null->r=null;}
 25 inline Node* NewNode(Node * last=NULL)
 26 {
 27     Node * ret=port++;
 28     if (last==NULL) {ret->Sum=0; ret->l=ret->r=null;}
 29     else {ret->Sum=last->Sum+1; ret->l=last->l; ret->r=last->r;}
 30     return ret;
 31 }
 32 //======================================
 33 int Begin[Maxn],End[Maxn],Dfn[Maxn],head[Maxn];
 34 int cnt,Stamp,u,v,Rank[Maxn],n,C[Maxn],a[Maxn],num;
 35 struct Info{int v,id;}Data[Maxn];
 36 struct EDGE{int to,next;}edge[Maxn<<1];
 37 inline bool Cmp(Info A,Info B) {return A.v<B.v;}
 38 inline void Add(int u,int v) {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
 39 void Dfs(int u,int fa)
 40 {
 41     Dfn[Begin[u]=++Stamp]=u;
 42     for (int i=head[u];i!=-1;i=edge[i].next) 
 43         if (edge[i].to!=fa) Dfs(edge[i].to,u);
 44     Dfn[End[u]=++Stamp]=u;
 45 }
 46 Node * Update(int l,int r,Node *x,int v)
 47 {
 48     Node * Ret=NewNode(x); 
 49     if (l==r) return Ret;
 50     int mid=(l+r)>>1;
 51     if (v<=mid)Ret->l=Update(l,mid,x->l,v); else
 52     Ret->r=Update(mid+1,r,x->r,v); 
 53     return Ret;
 54 }
 55 void Query(int L,int R,int K)
 56 {
 57     Node * x=Root[L-1],*y=Root[R];
 58     int P=1,Q=num;
 59     while (P!=Q)
 60     {
 61         int mid=(P+Q)>>1;
 62         if (P==Q) 
 63         {
 64             printf("%d\\n",C[P]);
 65             return;
 66         }
 67         if (y->l->Sum-x->l->Sum<K)
 68         {
 69             K-=(y->l->Sum-x->l->Sum);
 70             x=x->r,y=y->r;
 71             P=mid+1;
 72         } else
 73         {
 74             x=x->l,y=y->l;
 75             Q=mid;
 76         }
 77     }
 78     printf("%d\\n",C[P]);
 79     return;
 80 }
 81 int main()
 82 {
 83     // freopen("c.in","r",stdin);
 84     scanf("%d",&n); Init(); Root[0]=NewNode();
 85     for (int i=1;i<=n;i++) 
 86         scanf("%d",&a[i]),Data[i].v=a[i],Data[i].id=i;
 87     sort(Data+1,Data+n+1,Cmp);
 88     for (int i=1;i<=n;i++)
 89         C[++num]=Data[i].id,Rank[Data[i].id]=num;
 90     memset(head,-1,sizeof(head));
 91     for (int i=1;i<n;i++)
 92     {
 93         scanf("%d%d",&u,&v);
 94         Add(u,v),Add(v,u);
 95     }
 96     Dfs(1,0);
 97      
 98      
 99     for (int i=1;i<=Stamp;i++) 
100         Root[i]=Update(1,num,Root[i-1],Rank[Dfn[i]]);
101     int m,x,k;
102     scanf("%d",&m);
103     for (int i=1;i<=m;i++)
104     {
105         scanf("%d%d",&x,&k); k=k*2;
106         Query(Begin[x],End[x],k);
107     }
108     return 0;
109 }
POJ1803

BZOJ 3364 LCA

 1  
 2 #include <cstdio>
 3 #include <cstring>
 4 const int Maxn=400100;
 5 struct EDGE{int to,next,w;}edge[Maxn<<1];
 6 int head[Maxn],Size[Maxn],Dep[Maxn],Top[Maxn],Dis[Maxn],Fa[Maxn],n,m,u,v,w,cnt,Q;
 7 inline void Add(int u,int v,int w) {edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt++;}
 8 void Dfs1(int u,int fa)
 9 {
10     Size[u]=1;
11     for (int i=head[u];i!=-1;i=edge[i].next)
12     {
13         if (edge[i].to==fa) continue;
14         Dep[edge[i].to]=Dep[u]+1; Fa[edge[i].to]=u; 
15         Dis[edge[i].to]=Dis[u]+edge[i].w;
16         Dfs1(edge[i].to,u);
17         Size[u]+=Size[edge[i].to];
18     }
19 }
20 void Dfs2(int u,int fa,int chain)
21 {
22     int k=0; Top[u]=chain;
23     for (int i=head[u];i!=-1;i=edge[i].next)
24     {
25         if (edge[i].to==fa) continue; 
26         if (Size[edge[i].to]>Size[k] || k==0) k=edge[i].to;
27     }
28     if (k==0) return;
29     Dfs2(k,u,chain);
30     for (int i=head[u];i!=-1;i=edge[i].next)
31         if (edge[i].to!=fa && edge[i].to!=k)
32             Dfs2(edge[i].to,u,edge[i].to);
33 }
34 int Lca(int u,int v)
35 {
36     while (true)
37     {
38         if (Top[u]==Top[v]) return Dep[u]>Dep[v]?v:u;
39         if (Dep[Top[u]]>Dep[Top[v]]) u=Fa[Top[u]]; else v=Fa[Top[v]];
40     }
41 }
42 int main()
43 {
44     // freopen("c.in","r",stdin);
45     while (scanf("%d%d",&n,&m)!=EOF)
46     {
47         memset(head,-1,sizeof(head));
48         char Str[5];
49         for (int i=1;i<=m;i++)
50         {
51             scanf("%d%d%d%s",&u,&v,&w,Str);
52             Add(u,v,w),Add(v,u,w);
53         }
54         Dep[1]=1; Fa[1]=1; Dis[1]=0;
55         Dfs1(1,0);
56         Dfs2(1,0,1);
57         scanf("%d",&Q);
58         for (int i=1;i<=Q;i++) 
59         {
60             scanf("%d%d",&u,&v);
61             printf("%d\\n",Dis[u]+Dis[v]-2*Dis[Lca(u,v)]);
62         }
63     }
64     return 0;
65 }
树链剖分 LCA
 1 #include <cstdio>
 2 #include <cstring>
 3 const int Maxn=400100;
 4 struct EDGE{int to,next,w;}edge[Maxn<<1];
 5 int head[Maxn],Dep[Maxn],Dis[Maxn],Fa[Maxn][20],n,m,u,v,w,cnt,Q;
 6 inline void Add(int u,int v,int w) {edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt++;}
 7 inline void Swap(int &x,int &y){int t=x;x=y;y=t;}
 8 void Dfs(int u,int fa)
 9 {
10     for (int i=head[u];i!=-1;i=edge[i].next)
11     {
12         if (edge[i].to==fa) continue;
13         Dep[edge[i].to]=Dep[u]+1; Fa[edge[i].to][0]=u; 
14         Dis[edge[i].to]=Dis[u]+edge[i].w;
15         Dfs(edge[i].to,u);
16     }
17 }
18 inline void Init()
19 {
20     for (int i=1;i<=18;i++)
21         for (int j=1;j<=n;j++) Fa[j][i]=Fa[Fa[j][i-1]][i-1];
22 }
23 inline int Lca(int u,int v)
24 {
25     if (Dep[u]>Dep[v]) Swap(u,v);    
26     int Len=Dep[v]-Dep[u];
27     for (int i=0;i<=18;i++)
28         if (Len&(1<<i)) v=Fa[v][i];
29     for (int i=18;i>=0;i--)
30         if (Fa[u][i]!=Fa[v][i]) u=Fa[u][i],v=Fa[v][i];
31     if (u!=v) return Fa[u][0];
32     return u;
33 }
34 int main()
35 {
36     // freopen("c.in","r",stdin);
37     while (scanf("%d%d",&n,&m)!=EOF)
38     {
39         memset(head,-1,sizeof(head));
40         char Str[5];
41         for (int i=1;i<=m;i++)
42         {
43             scanf("%d%d%d%s",&u,&v,&w,Str);
44             Add(u,v,w),Add(v,u,w);
45         }
46         Dep[1]=1; Fa[1][0]=1; Dis[1]=0;
47         Dfs(1,0); Init();
48         scanf("%d",&Q);
49         for (int i=1;i<=Q;i++) 
50         {
51             scanf("%d%d",&u,&v);
52             printf("%d\\n",Dis[u]+Dis[v]-2*Dis[Lca(u,v)]);
53         }
54     }
55     return 0;
倍增 LCA

BZOJ 1699 RMQ

 1 #include <cstdio>
 2 #include <cmath>
 3 const int Maxn=50100;
 4 int FMax[Maxn][20],FMin[Maxn][20],n,q,l,r,x;
 5 inline int Min(int x,int y) {return x>y?y:x;}
 6 inline int Max(int x,int y) {return x>y?x:y;}
 7 inline void Init()
 8 {
 9     for (int i=1;i<=18;i++)
10         for (int j=1;j+(1<<(i-1))<=n;j++)
11         {
12             FMax[j][i]=Max(FMax[j+(1<<(i-1))][i-1],FMax[j][i-1]);
13             FMin[j][i]=Min(FMin[j+(1<<(i-1))][i-1],FMin[j][i-1]);
14         }
15 }
16 inline int Query(int l,int r)
17 {
18     int Len=(int)log2(r-l+1);
19      
20     return Max(FMax[l][Len],FMax[r-(1<<Len)+1][Len])-Min(FMin[l][Len],FMin[r-(1<<Len)+1][Len]);
21 }
22 int main()
23 {
24     // freopen("c.in","r",stdin);
25     scanf("%d%d",&n,&q);
26     for (int i=1;i<=n;i++) scanf("%d",&x),FMax[i][0]=x,FMin[i][0]=x;
27     Init();
28     for (int i=1;i<=q;i++)
29     {
30         scanf("%d%d",&l,&r);
31         printf("%d\\n",Query(l,r));
32     }
33     return 0;
34 }
RMQ

 

以上是关于NOIP 考前 数据结构复习的主要内容,如果未能解决你的问题,请参考以下文章

NOIP 考前DP 复习

NOIP 考前 数论复习

noip2017考前基础复习——数论数学

NOIP考纲总结+NOIP考前经验谈

[NOIP2017]考前注意事项

NOIP考前临时抱佛脚(算是考前日记吧)