zoukankan      html  css  js  c++  java
  • Uva 12299 带循环移动的RMQ(线段树)

    题目链接:https://vjudge.net/contest/147973#problem/C

    题意:传统的RMQ是一个不变的数组a求区间最值。现在要循环移动(往前移动)。

    分析:求区间问题,很容易想到线段树,移动就相当于单点更新。

    建树,有两种方案,第一种是nlogn,就是不断的更新,更新logn,有n个数。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 
     6 const int INF = 1000000000;
     7 const int maxnode = 1<<18;
     8 
     9 int op, qL, qR, p, v;   //qL,qR询问区间,p修改点,v修改值
    10 
    11 struct IntervalTree
    12 {
    13     int minv[maxnode];
    14 
    15     //修改:A[p] = v;
    16     void update (int o,int L,int R)
    17     {
    18         int M = L + (R-L)/2;
    19         if(L==R) minv[o] = v;
    20         else
    21         {
    22             if(p<=M) update(o*2,L,M);
    23             else update(o*2+1,M+1,R);
    24             minv[o] = min(minv[o*2],minv[o*2+1]);
    25         }
    26     }
    27 
    28     //询问[ql,qr]中的最小值
    29     int query(int o,int L,int R)
    30     {
    31         int M = L+(R-L)/2,ans = INF;
    32         if(qL<=L&&R<=qR) return minv[o];
    33         if(qL<=M) ans = min(ans,query(o*2,L,M));
    34         if(M<qR) ans = min(ans,query(o*2+1,M+1,R));
    35         return ans;
    36     }
    37 
    38 };
    39 
    40 IntervalTree tree;
    41 const int maxn = 100000 + 10;
    42 int A[maxn];
    43 
    44 int main()
    45 {
    46     int n,q;
    47     memset(&tree,0,sizeof(tree));
    48 
    49     scanf("%d%d",&n,&q);
    50 
    51     for(p=1; p<=n; p++)
    52     {
    53         scanf("%d",&v);
    54         A[p] = v;
    55         tree.update(1,1,n);
    56     }
    57 
    58     int k,args[20],original[20];
    59     char cmd[100];
    60     while(q--)
    61     {
    62         scanf("%s", cmd);
    63         int len = strlen(cmd);
    64         k = 0;
    65         args[k] = 0;
    66         for(int i = 6; i < len; i++)
    67         {
    68             if(isdigit(cmd[i])) args[k] = args[k] * 10 + cmd[i] - '0';
    69             else
    70             {
    71                 k++;
    72                 args[k] = 0;
    73             }
    74         }
    75         if(cmd[0] == 'q')
    76         {
    77             qL = args[0];
    78             qR = args[1];
    79             printf("%d
    ", tree.query(1, 1, n));
    80         }
    81         else
    82         {
    83             for(int i = 0; i < k; i++) original[i] = A[args[i]];
    84             for(int i = 0; i < k; i++)
    85             {
    86                 p = args[i];
    87                 v = A[p] = original[(i+1)%k];
    88                 tree.update(1, 1, n);
    89             }
    90         }
    91     }
    92     return 0;
    93 }

     第二种是有一个build的过程,先将数组存起来,然后build,应用到要维护的信息上去。

      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 
      6 const int INF = 1000000000;
      7 const int maxnode = 1<<18;
      8 
      9 const int maxn = 100000 + 10;
     10 int A[maxn];
     11 int op, qL, qR, p, v;
     12 
     13 struct IntervalTree
     14 {
     15     int minv[maxnode];
     16 
     17 
     18     void build(int o,int L,int R)
     19     {
     20         int M = L + (R-L)/2;
     21         if(L==R) minv[o] = A[L];
     22         else
     23         {
     24             build(o*2,L,M);
     25             build(o*2+1,M+1,R);
     26             minv[o] = min(minv[o*2],minv[o*2+1]);
     27         }
     28     }
     29 
     30     //点修改 d[p] =v;
     31     void update(int o,int L,int R)
     32     {
     33         int M = L + (R-L)/2;
     34         if(L==R) minv[o] = v;
     35         else
     36         {
     37             if(p<=M) update(o*2,L,M);
     38             else update(o*2+1,M+1,R);
     39             minv[o] = min(minv[o*2],minv[o*2+1]);
     40         }
     41     }
     42 
     43     int query(int o,int L,int R)
     44     {
     45 
     46         int M = L + (R-L)/2,ans=INF;
     47         if(qL<=L&&R<=qR)
     48             return minv[o];
     49 
     50         if(qL<=M) ans = min(ans,query(o*2,L,M));
     51         if(M<qR) ans = min(ans,query(o*2+1,M+1,R));
     52 
     53         return ans;
     54     }
     55 
     56 };
     57 
     58 IntervalTree tree;
     59 
     60 int main()
     61 {
     62     int n,q;
     63     scanf("%d%d",&n,&q);
     64     memset(&tree,0,sizeof(tree));
     65     for(int i=1; i<=n; i++)
     66         scanf("%d",&A[i]);
     67     tree.build(1,1,n);
     68 
     69     int k,args[20],original[20];
     70     char cmd[100];
     71     while(q--)
     72     {
     73         scanf("%s", cmd);
     74         int len = strlen(cmd);
     75         k = 0;
     76         args[k] = 0;
     77         for(int i = 6; i < len; i++)
     78         {
     79             if(isdigit(cmd[i])) args[k] = args[k] * 10 + cmd[i] - '0';
     80             else
     81             {
     82                 k++;
     83                 args[k] = 0;
     84             }
     85         }
     86         if(cmd[0] == 'q')
     87         {
     88             qL = args[0];
     89             qR = args[1];
     90             printf("%d
    ", tree.query(1, 1, n));
     91         }
     92         else
     93         {
     94             for(int i = 0; i < k; i++) original[i] = A[args[i]];
     95             for(int i = 0; i < k; i++)
     96             {
     97                 p = args[i];
     98                 v = A[p] = original[(i+1)%k];
     99                 tree.update(1, 1, n);
    100             }
    101         }
    102     }
    103     return 0;
    104 }
  • 相关阅读:
    mysql——前面内容——前期整理笔记00
    mysql——触发器——概念
    mysql——触发器——示例
    mysql——多表——外连接查询——左连接、右连接、复合条件查询
    mysql——多表——合并查询结果
    IT职场人生系列之七:学外语
    IT职场人生系列之十三:技术?管理?业务?
    IT职场人生系列之五:怎样面试
    IT职场人生系列之十二:语言与技术I
    IT职场人生系列之四:怎样写简历
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6336923.html
Copyright © 2011-2022 走看看