数据结构习题 线段树&树状数组

说明:这是去年写了一半的东西,一直存在草稿箱里,今天整理东西的时候才发现,还是把它发表出来吧。。


 

以下所有题目来自Lrj的《训练指南》

LA 2191

         单点修改,区间和  Fenwick直接搞

UVa 12299

         给出n个数,支持循环移动某些数(<30个),然后问区间最小值

         因为移动小于30个数,所以直接单点修改就行,线段树。

 

LA 4108

         类似线段树,每次插入一个建筑时想线段树一样二分区间,当遇到一个完整的区间时,修改或返回,否则继续二分区间。Nlogn.

UVa 11525

         有题解说可以逆向考虑用线段树,我没明白怎么回事。

   说一下我的做法:

   考虑问题(k,n)表示1~k的全排列中第n个。显然1~k的全排列可以分为k种,每种有(k-1)!种情况,那么如果确定了第n个排列属于哪一种,问题就转化为了(k-1,m);

    再考虑题目的输入。N的输入形式正好是按以上思想给出的,那么我们是需要把这个式子转化为标准形式即可。

   判断每个Si,若Si>(k-i+1),就要”进位”。所以从后向前扫描,可以在O(n)时间内解决。

LA 4730

         并查集+线段树。用并查集维护每个州,同时维护每个州的上端点(up)和下端点(down)。

         用线段树维护[a,b]内有多少个城市。方法是连接A和B时,[A.down,A.up]-=A.count; [B.down,B.up]-=B.count;  [new.down,new.up]+=new.count;

二维线段树

  先存一下(以下代码仅供参考 准确性无法保证233)

View Code
  1 #include <cstdio>

  2 #include <cstdlib>

  3 #include <iostream>

  4 #include <cstring>

  5 #define RS(x) (x*2+1)

  6 #define LS(x) (x*2)

  7 #define bigger(a,b) ((a)>(b)?(a):(b))

  8 #define minner(a,b) ((a)<(b)?(a):(b))

  9 #define MAXN (2000+10)

 10 #define root (1)

 11 #define INF (9999999)

 12 using namespace std;

 13 struct Segment_Tree_2D{

 14     struct treeY{

 15         int max,min;

 16         int L,R;

 17         int mid;

 18     };

 19     typedef struct treeY treeY;

 20     struct treeX{

 21         treeY T[MAXN];

 22         int L,R;

 23         int mid;

 24     };

 25     typedef struct treeX treeX;

 26     int x1,x2,y1,y2,val,max_ans,min_ans,x0,y0;

 27     treeX t[MAXN];

 28     void queryY(int f,int r,int fa,int p){//ok

 29         if (r>t[fa].T[p].R)   r=t[fa].T[p].R;

 30         if (f<t[fa].T[p].L)   f=t[fa].T[p].L;

 31         if (f==t[fa].T[p].L&&r==t[fa].T[p].R){

 32             max_ans=bigger(max_ans,t[fa].T[p].max);

 33             min_ans=minner(min_ans,t[fa].T[p].min);

 34         }else{

 35             int mid=t[fa].T[p].mid;

 36             if (r>mid)  queryY(mid+1,r,fa,RS(p));

 37             if (f<=mid) queryY(f,mid,fa,LS(p));

 38         }

 39     }

 40     void queryX(int f,int r,int p){//ok

 41         if (r>t[p].R)   r=t[p].R;

 42         if (f<t[p].L)   f=t[p].L;

 43         if (f==t[p].L&&r==t[p].R){

 44             queryY(y1,y2,p,root);

 45         }else{

 46             int mid=t[p].mid;

 47             if (r>mid)    queryX(mid+1,r,RS(p));

 48             if (f<=mid)   queryX(f,mid,LS(p));

 49         }

 50     }

 51     void modifyY(int fa,int p){//ok

 52         if (y0==t[fa].T[p].L&&y0==t[fa].T[p].R){

 53             t[fa].T[p].min=val;

 54             t[fa].T[p].max=val;

 55         }else{

 56             int mid=t[fa].T[p].mid;

 57             if (y0>mid)     modifyY(fa,RS(p));

 58             if (y0<=mid)    modifyY(fa,LS(p));

 59         }

 60         t[fa].T[p].max=bigger(t[fa].T[LS(p)].max,t[fa].T[RS(p)].max);

 61         t[fa].T[p].min=minner(t[fa].T[LS(p)].min,t[fa].T[RS(p)].min);

 62     }

 63     void maintainY(int fa,int p){//ok

 64         if (y0==t[fa].T[p].L&&y0==t[fa].T[p].R){

 65             t[fa].T[p].min=minner(t[LS(fa)].T[p].min,t[RS(fa)].T[p].min);

 66             t[fa].T[p].max=bigger(t[LS(fa)].T[p].max,t[RS(fa)].T[p].max);

 67         }else{

 68             int mid=t[fa].T[p].mid;

 69             if (y0>mid) maintainY(fa,RS(p));

 70             if (y0<=mid) maintainY(fa,LS(p));

 71         }

 72         t[fa].T[p].max=bigger(t[fa].T[LS(p)].max,t[fa].T[RS(p)].max);

 73         t[fa].T[p].min=minner(t[fa].T[LS(p)].min,t[fa].T[RS(p)].min);

 74     }

 75     void modifyX(int p){

 76         if (x0==t[p].L&&x0==t[p].R){

 77             modifyY(p,root);

 78         }else{

 79             int mid=t[p].mid;

 80             if (x0>mid)     modifyX(RS(p));

 81             if (x0<=mid)    modifyX(LS(p));

 82             maintainY(p,root);

 83         }

 84     }

 85 

 86     void query(){max_ans=-INF;min_ans=INF;queryX(x1,x2,root);}

 87     void modify(){modifyX(root);}

 88 };

 89 typedef struct Segment_Tree_2D ST2;

 90 ST2 t;

 91 int main()

 92 {

 93     int i,j,n,m,temp,q;

 94     char cmd[10];

 95     scanf("%d%d",&n,&m);

 96     for (i=1;i<=n;i++){

 97         for (j=1;j<=m;j++){

 98             scanf("%d",&temp);

 99             t.x0=i; t.y0=j;

100             t.modify();

101         }

102     }

103     scanf("%d",&q);

104     for (i=0;i<q;i++){

105         scanf("%s",cmd);

106         if (cmd[0]=='q'){

107             scanf("%d%d%d%d",&t.x1,&t.y1,&t.x2,&t.y2);

108             t.query();

109             printf("%d %d\n",t.max_ans,t.min_ans);

110         }else{

111             scanf("%d%d",&t.x0,&t.y0);

112             t.modify();

113         }

114     }

115     return 0;

116 }

 

你可能感兴趣的:(数据结构)