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


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


    以下所有题目来自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
    ",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 }
  • 相关阅读:
    Surface RT2装Win10出现 "INF不包含数字签名信息"【已解决】
    树上倍增LCA模版
    sql注入
    python 调用 telnet
    ss
    【总结氵】2021.02.27 省选模拟
    2021.03.13省选模拟 抽卡(card)
    树链剖分之重链剖分 模板
    多项式求逆 模板
    NTT快速数论变换 模板
  • 原文地址:https://www.cnblogs.com/loveidea/p/2981703.html
Copyright © 2020-2023  润新知