一堆模板(丑陋0.0)------数据结构

 1 //1.主席树模板练习--HDU2665 Kth number 
 2 //0.0
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<cstdio>
 7 #include<cstdlib>
 8 #include<cmath>
 9 #include<cstring>
10 using namespace std;
11 struct tree{
12             int val,l,r;
13            }t[2000000];
14 int tot,a[100000],n,m,u[100000],root[100000];
15 int build_tree(int l,int r)
16 {
17     int now=tot++;
18     t[now].val=0;
19     if (l!=r)
20        {
21         int m=(l+r)>>1;
22         t[now].l=build_tree(l,m);
23         t[now].r=build_tree(m+1,r);
24        }
25     return now;
26 } 
27 int next(int last,int l,int r,int rank)
28 {
29     int now=tot++;
30     t[now]=t[last];
31     t[now].val++;
32     if (l!=r)
33        {
34         int m=(l+r)>>1;
35         if (rank<=m) t[now].l=next(t[last].l,l,m,rank);
36         else t[now].r=next(t[last].r,m+1,r,rank);
37        }
38     return now;
39 }
40 int scr(int up,int down,int l,int r,int k)
41 {
42     if (l==r) return l;
43     int m=(l+r)>>1;
44     int lnum=t[t[up].l].val-t[t[down].l].val;
45     if (k<=lnum) return scr(t[up].l,t[down].l,l,m,k);
46     else return scr(t[up].r,t[down].r,m+1,r,k-lnum);
47 }
48 int main()
49 {
50     freopen("in.in","r",stdin); freopen("out.out","w",stdout);
51     int T;
52     cin>>T;
53     while (T--)
54           {
55            cin>>n>>m;
56            for (int i=0;i<n;i++) {cin>>a[i]; u[i]=a[i];}
57            sort(u,u+n);
58            int len=unique(u,u+n)-u;
59            tot=0; root[0]=build_tree(1,len);
60            for (int i=0;i<n;i++)
61                {
62                 int rank=lower_bound(u,u+len,a[i])-u+1;
63                 root[i+1]=next(root[i],1,len,rank);
64                }
65            while (m--)
66                  {
67                   int l,r,k;
68                   cin>>l>>r>>k;
69                   cout<<u[scr(root[r],root[l-1],1,len,k)-1]<<endl;      
70                  } 
71           }
72     return 0;
73 }

 

2.线段树

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<cmath>
  7 #define llg long long 
  8 #define maxn 200000*3+10
  9 using namespace std;
 10 
 11 llg i,j,ans,k,x,n,m,sum[maxn],set[maxn],addv[maxn],type,y,v,bj[maxn]/*是否具有set标记*/;
 12 
 13 void build(llg o,llg l,llg r)
 14 {
 15     if (l==r) 
 16     {
 17         scanf("%lld",&sum[o]);
 18     }
 19     else{
 20         llg mid=(l+r)/2;
 21         build(o*2,l,mid);
 22         build(o*2+1,mid+1,r);
 23         sum[o]=sum[o*2]+sum[o*2+1];
 24         }
 25 }
 26 
 27 void pushdown(llg o,llg l,llg r)
 28 {
 29     llg lc=o*2,rc=o*2+1,mid=(r+l)/2;
 30     if (bj[o])
 31     {
 32         bj[o]=0; bj[lc]=bj[rc]=1;
 33         set[lc]=set[rc]=set[o];
 34         sum[lc]=set[o]*(mid-l+1);
 35         sum[rc]=set[o]*(r-mid);
 36         addv[lc]=addv[rc]=0;
 37     }
 38     if (addv[o])
 39     {
 40         addv[lc]+=addv[o]; addv[rc]+=addv[o];
 41         sum[lc]+=addv[o]*(mid-l+1);
 42         sum[rc]+=addv[o]*(r-mid);addv[o]=0;
 43     }
 44 }
 45 
 46 void add(llg o,llg l,llg r)
 47 {
 48     pushdown(o,l,r);
 49     if (l>=x && r<=y)
 50     {
 51         addv[o]+=v; sum[o]+=(r-l+1)*v;
 52         return ;
 53     }    
 54     llg lc=o*2,rc=o*2+1,mid=(r+l)/2;
 55     if (x<=mid) add(lc,l,mid);
 56     if (y>mid) add(rc,mid+1,r);
 57     sum[o]=sum[lc]+sum[rc];
 58 }
 59 
 60 void sum_(llg o,llg l,llg r)
 61 {
 62     pushdown(o,l,r);
 63     if (l>=x && r<=y)
 64     {
 65         ans+=sum[o];
 66         return ;
 67     }
 68     llg lc=o<<1,rc=o<<1|1,mid=(r+l)>>1;
 69     if (x<=mid) sum_(lc,l,mid);
 70     if (y>mid) sum_(rc,mid+1,r);
 71 }
 72 void seet(llg o,llg l,llg r)
 73 {
 74     
 75 } 
 76 int main()
 77 {
 78     freopen("in.in","r",stdin); freopen("out.out","w",stdout);
 79     cin>>n;
 80     build(1,1,n); 
 81     cin>>m;
 82     while (m--)
 83     {
 84         scanf("%lld",&type);
 85         if (type==1)//add
 86         {
 87             scanf("%lld%lld%lld",&x,&y,&v);
 88             add(1,1,n);
 89         }
 90         if (type==3)//set
 91         {
 92             scanf("%lld%lld%lld",&x,&y,&v);
 93             seet(1,1,n);
 94         }
 95         if (type==2)//sum
 96         {
 97             ans=0;
 98             scanf("%lld%lld",&x,&y);
 99             sum_(1,1,n);
100             printf("%lld\n",ans);
101         }
102     }
103     return 0;
104 }

 

3.spaly

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<cstring>
 7 #define ll long long 
 8 #define maxn 100010
 9 ll father[maxn],rightson[maxn],leftson[maxn],root;
10 using namespace std;
11 void right_rotate(ll x)//右旋 
12 {
13     ll y=father[x],z=father[y];
14     leftson[y]=rightson[x];
15     if (rightson[x]!=0) father[rightson[x]]=y;//处理x的右子树
16     father[x]=z;
17     if (z!=0)
18         {
19             if (leftson[z]==y) leftson[z]=x;else rightson[z]=x;
20         }
21     rightson[x]=y; father[y]=x;
22 }
23 /*
24 右旋只需要三步:
25 1.将X的右子树B(如果有的话)作为Y的左子树,同时让B认Y作爹
26 2.设Z为原本Y结点的父亲,让X认Z做爹(如果Z存在的话),将X作为Z的儿子(是左是右得由Y是Z的左儿子还是右儿子决定,要左右一致)
27 3.将Y作为X的右子树,同时让Y认X作爹
28 */
29 void left_rotate(ll x)  
30 {  
31      ll y=father[x],z=father[y];  
32      rightson[y]=leftson[x];  
33      if(leftson[x]!=0)father[leftson[x]]=y;  
34      father[x]=z;  
35      if(z!=0)  
36      {  
37              if(leftson[z]==y)leftson[z]=x;else rightson[z]=x;  
38              }  
39      leftson[x]=y;father[y]=x;  
40 }  
41 void splay(ll x,ll llg)//表示将x不停向上旋转,知道X成为结点为llg的子树 
42 {  
43      while(father[x]!=llg)  
44      {  
45          long y=father[x];long z=father[y];  
46          if(z==llg)  
47          {  
48                         if(rightson[y]==x)left_rotate(x);else right_rotate(x);  
49                         }  
50          else  
51          {  
52                  if(rightson[z]==y && rightson[y]==x){left_rotate(y); left_rotate(x);}  
53             else if(rightson[z]==y && leftson[y]==x) {right_rotate(x); left_rotate(x);}  
54             else if(leftson[z]==y && leftson[y]==x)  {right_rotate(y); right_rotate(x);}  
55             else                                   {left_rotate(x); right_rotate(x);}  
56             }  
57             }  
58       if(llg==0) root=x;  
59 } 
60 ll findleft(ll x)//找这个节点左子树的最大值(前驱) 
61 {
62     ll left=leftson[x];
63     while (rightson[left]!=0)  left=rightson[left];
64     return left;
65 } 
66 ll findright(ll x)//找这个节点在右子树的最小值(后继) 
67 {
68     ll right=rightson[x];
69     while (leftson[right]!=0) right=leftson[right];
70     return right;
71 }
72 int main()
73 {
74     return 0;
75 }

 

4.并查集

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<vector>
 7 #define yyj(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout);
 8 #define llg long long
 9 using namespace std;
10 llg i,j,k,n,m,dad[200100],x,y;
11 llg find (llg x)
12 {
13     return dad[x]==x?x:dad[x]=find(dad[x]);
14 }
15 int main()
16 {
17     yyj("a");
18     cin>>n;
19     for (i=1;i<=n;i++) dad[i]=i;
20     cin>>m;
21     while (m--)
22     {
23         cin>>x>>y;
24         if (find(x)!=find(y)) dad[find(y)]=find(x);
25     }
26     cin>>m;
27     while (m--)
28     {
29         cin>>x>>y;
30         if (find(x)!=find(y)) cout<<"NO"<<endl;else cout<<"YES"<<endl;
31     }
32     return 0;
33 }

 

5.树状数组

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<vector>
 7 #define yyj(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout);
 8 #define llg long long
 9 using namespace std;
10 llg a[1000],i,j,k,n,m,c[1000],y,x,type;
11 llg lowbit(llg x)
12 {
13     return x&-x;
14 }
15 void add(llg w,llg v)
16 {
17     while (w<=n)
18     {
19         c[w]+=v; w+=lowbit(w);
20     }
21 }
22 llg sum(llg w)
23 {
24     llg ans=0;
25     while (w>0)
26         {
27             ans+=c[w]; w-=lowbit(w);
28         }
29     return ans;
30 }
31 int main()
32 {
33     yyj("a");
34     cin>>n;
35     for (i=1;i<=n;i++) 
36         {    
37             cin>>a[i];
38             add(i,a[i]);
39         }
40     cin>>m;
41     while (m--)
42     {
43         cin>>type;
44         if (type==1)
45         {
46             cin>>x>>y;
47             add(x,y);
48         }
49         if (type==2)
50         {
51             cin>>x>>y;
52             cout<<sum(y)-sum(x-1)<<endl;
53         }
54     }
55     return 0;
56 }

 

posted @ 2016-05-31 19:39  №〓→龙光←  阅读(173)  评论(0编辑  收藏  举报