亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

RMQ 詳解及 題目

系統(tǒng) 2837 0

RMQ(Range Minimum/Maximum Query)問題:
?

? RMQ問題是求給定區(qū)間中的最值問題。當然,最簡單的算法是O(n)的,但是對于查詢次數(shù)很多(設置多大100萬次),O(n)的算法效率不夠。可以用線 段樹將算法優(yōu)化到O(logn)(在線段樹中保存線段的最值)。不過,Sparse_Table算法才是最好的:它可以在O(nlogn)的預處理以后實 現(xiàn)O(1)的查詢效率。下面把Sparse Table算法分成預處理和查詢兩部分來說明(以求最小值為例)。

預處理:
預處理使用DP的思想,f(i, j)表示[i, i+2^j - 1]區(qū)間中的最小值,我們可以開辟一個數(shù)組專門來保存f(i, j)的值。
例如,f(0, 0)表示[0,0]之間的最小值,就是num[0], f(0, 2)表示[0, 3]之間的最小值, f(2, 4)表示[2, 17]之間的最小值
注意, 因為f(i, j)可以由f(i, j - 1)和f(i+2^(j-1), j-1)導出, 而遞推的初值(所有的f(i, 0) = i)都是已知的
所以我們可以采用自底向上的算法遞推地給出所有符合條件的f(i, j)的值。

        
          1
        
        
          for
        
        (
        
          int
        
         i=
        
          1
        
        ;i<=n;i++
        
          ) 


        
        
          2
        
            f[i,
        
          0
        
        ]:=
        
          a[i];


        
        
          3
        
        
          4
        
        
          for
        
        (
        
          int
        
         j=
        
          1
        
        ;j<=log(n)/log(
        
          2
        
        );j++
        
          )


        
        
          5
        
        
          {


        
        
          6
        
        
          for
        
        (
        
          int
        
         i=
        
          1
        
        ;i<=n+
        
          1
        
        -
        
          1
        
        <<j;j++
        
          ) 


        
        
          7
        
              f[i,j]=max(f[i,j-
        
          1
        
        ],f[i+
        
          1
        
        <<(j-
        
          1
        
        ),j-
        
          1
        
        
          ]);  


        
        
          8
        
         };
      

?

查詢:
假設要查詢從m到n這一段的最小值, 那么我們先求出一個最大的k, 使得k滿足2^k <= (n - m + 1).
于是我們就可以把[m, n]分成兩個(部分重疊的)長度為2^k的區(qū)間: [m, m+2^k-1], [n-2^k+1, n];


而我們之前已經(jīng)求出了f(m, k)為[m, m+2^k-1]的最小值, f(n-2^k+1, k)為[n-2^k+1, n]的最小值

        
          1
        
        
          long
        
         query(
        
          long
        
         l,
        
          long
        
        
           r)


        
        
          2
        
        
          {


        
        
          3
        
        
          long
        
         x=log(r-l+
        
          1
        
        )/log(
        
          2
        
        
          );


        
        
          4
        
        
          return
        
         (max(f[l,x],f[r+
        
          1
        
        -
        
          1
        
        <<
        
          x,x]));


        
        
          5
        
         }
      

?


我們只要返回其中更小的那個, 就是我們想要的答案, 這個算法的時間復雜度是O(1)的.
例如, rmq(0, 11) = min(f(0, 3), f(4, 3))

感想:對于一個數(shù)組里的固定長度的區(qū)間,可以只開一個n*1維數(shù)組,算f(i,j)的時候可以將f(i,j-1)覆蓋,因為用到的只是上一列的情況。

?

題目:

poj 3368 Frequent values

http://poj.org/problem?id=3368

?

題意 : 給定 一個 遞增的數(shù)組 a?? 給出 q 次詢問 求出 l? 到 r? 最多的???? 數(shù)字相同的個數(shù)

?

如 :10 3 -1 -1 1 1 1 1 3 10 10 10

輸入 1 10

輸出? 4

? 1 到10 出現(xiàn)最多的是 1 出現(xiàn)了 4 次

?

題解: 將 連續(xù)相同的點 縮成一個節(jié)點 ,這個節(jié)點包括三個部分? 初始位置 ,結(jié)束位置 ,個數(shù)
? 那么詢問時 包括三種情況
? 1:l 和 r同屬于? 一個節(jié)點?? 那么 ans = r - l + 1
? ?
? 2: 屬于相鄰的連個節(jié)點? ans =? max ( p[hash[l]].t - l +1,r - p[hash[r]].s + 1);
? 3: 屬于? l 和 r之間有好幾個節(jié)點?? hash[l]+1? 到 hash[r] - 1 的最大值 和 情況 2 進

View Code
          
             1
          
           #include<cstdio>


          
             2
          
           #include<cmath>


          
             3
          
           #include<cstring>


          
             4
          
           #include<iostream>


          
             5
          
           #include<algorithm>


          
             6
          
           #include<
          
            set
          
          >


          
             7
          
           #include<map>


          
             8
          
           #include<queue>


          
             9
          
           #include<vector>


          
            10
          
           #include<
          
            string
          
          >


          
            11
          
          
            #define
          
           Min(a,b) a<b?a:b


          
            12
          
          
            #define
          
           Max(a,b) a>b?a:b


          
            13
          
          
            #define
          
           CL(a,num) memset(a,num,sizeof(num));


          
            14
          
          
            #define
          
           maxn  100010


          
            15
          
          
            #define
          
           inf 9999999


          
            16
          
          
            17
          
          
            #define
          
            mod   9973


          
            18
          
          
            #define
          
           ll  long long


          
            19
          
          
            using
          
          
            namespace
          
          
             std;


          
          
            20
          
          
            int
          
          
             hash[maxn],a[maxn];


          
          
            21
          
          
            int
          
           dp[maxn][
          
            30
          
          
            ],id;


          
          
            22
          
          
            23
          
          
            struct
          
          
             node


          
          
            24
          
          
            {


          
          
            25
          
          
            int
          
          
             s;


          
          
            26
          
          
            int
          
          
             t;


          
          
            27
          
          
            int
          
          
             w;


          
          
            28
          
          
            29
          
          
            }p[maxn];


          
          
            30
          
          
            void
          
          
             rmq_init()


          
          
            31
          
          
            {


          
          
            32
          
          
            int
          
          
             i , j;


          
          
            33
          
          
            34
          
          
            for
          
          ( i = 
          
            0
          
          ; i <= id;++i)dp[i][
          
            0
          
          ] =
          
             p[i].w;


          
          
            35
          
          
            int
          
           k = log(
          
            double
          
          (id+
          
            1.0
          
          ))/log(
          
            2.0
          
          );
          
            //
          
          
            36
          
          
            37
          
          
            for
          
          ( i = 
          
            1
          
          ;i <= k; ++
          
            i)


          
          
            38
          
          
                {


          
          
            39
          
          
            int
          
           s = (
          
            1
          
           << i-
          
            1
          
          ) - 
          
            1
          
          
            ;


          
          
            40
          
          
            for
          
          (j = 
          
            1
          
          ;j + (
          
            1
          
           << i)-
          
            1
          
           <= id ;++
          
            j)


          
          
            41
          
          
                    {


          
          
            42
          
                       dp[j][i] = max(dp[j][i - 
          
            1
          
          ],dp[j + s ][i - 
          
            1
          
          
            ]);


          
          
            43
          
          
                    }


          
          
            44
          
          
                }


          
          
            45
          
          
            }


          
          
            46
          
          
            int
          
          
            get
          
          (
          
            int
          
           l,
          
            int
          
          
             r)


          
          
            47
          
          
            {


          
          
            48
          
          
            int
          
           k = log(
          
            double
          
          (r - l +
          
            1.0
          
          ))/log(
          
            2.0
          
          );
          
            //
          
          
            求的是 求出最大的k,滿足2^k<=R-L+1
          
          
            49
          
          
            int
          
           s = 
          
            1
          
           <<
          
             k;


          
          
            50
          
          
            return
          
           max(dp[l][k],dp[r - s + 
          
            1
          
          
            ][k]);


          
          
            51
          
          
            }


          
          
            52
          
          
            int
          
          
             main()


          
          
            53
          
          
            {


          
          
            54
          
          
            int
          
          
             n,m,i,l,r;


          
          
            55
          
          
            while
          
          (scanf(
          
            "
          
          
            %d
          
          
            "
          
          ,&
          
            n),n)


          
          
            56
          
          
                {


          
          
            57
          
                   scanf(
          
            "
          
          
            %d
          
          
            "
          
          ,&
          
            m);


          
          
            58
          
          
            for
          
          ( i = 
          
            1
          
          ;i <=n; ++i)scanf(
          
            "
          
          
            %d
          
          
            "
          
          ,&
          
            a[i]);


          
          
            59
          
          
            60
          
                   memset(p,
          
            0
          
          ,
          
            sizeof
          
          
            (p));


          
          
            61
          
                    id = 
          
            1
          
          
            ;


          
          
            62
          
                   p[
          
            1
          
          ].s = 
          
            1
          
          
            ;


          
          
            63
          
          
            64
          
          
            for
          
          ( i = 
          
            1
          
          ; i <= n ;++
          
            i)


          
          
            65
          
          
                    {


          
          
            66
          
                       hash[i] =
          
             id ;


          
          
            67
          
                       p[id].w++
          
            ;


          
          
            68
          
          
            if
          
          ( a[i] != a[i+
          
            1
          
          ] || i ==
          
             n)


          
          
            69
          
          
                        {


          
          
            70
          
                           p[id].t =
          
             i;


          
          
            71
          
          
            if
          
          (i == n)
          
            break
          
          
            ;


          
          
            72
          
                           id++
          
            ;


          
          
            73
          
                           p[id].s = i + 
          
            1
          
          
             ;


          
          
            74
          
          
            75
          
          
                        }


          
          
            76
          
          
            77
          
          
                    }


          
          
            78
          
          
                     rmq_init();


          
          
            79
          
          
            80
          
          
            while
          
          ( m--
          
            )


          
          
            81
          
          
                     {


          
          
            82
          
                        scanf(
          
            "
          
          
            %d%d
          
          
            "
          
          ,&l,&
          
            r);


          
          
            83
          
          
            if
          
          (hash[l] == hash[r])printf(
          
            "
          
          
            %d\n
          
          
            "
          
          ,r - l + 
          
            1
          
          
            );


          
          
            84
          
          
            else
          
          
            85
          
          
                         {


          
          
            86
          
          
            int
          
           num1 = p[hash[l]].t - l +
          
            1
          
          
            ;


          
          
            87
          
          
            int
          
           num2 = r - p[hash[r]].s + 
          
            1
          
          
            ;


          
          
            88
          
          
            int
          
           num3 = 
          
            0
          
          
            ;


          
          
            89
          
          
            if
          
          (hash[r] - hash[l] > 
          
            1
          
          
            )


          
          
            90
          
                           num3 = 
          
            get
          
          (hash[l]+
          
            1
          
          ,hash[r]-
          
            1
          
          
            );


          
          
            91
          
          
            int
          
           ans =
          
             max(max(num1,num2),num3);


          
          
            92
          
                           printf(
          
            "
          
          
            %d\n
          
          
            "
          
          
            ,ans);


          
          
            93
          
          
                         }


          
          
            94
          
          
                     }


          
          
            95
          
          
                }


          
          
            96
          
           }
        

?

?

poj? 3264??? Balanced Lineup

http://poj.org/problem?id=3264

?

題意 : 給定 一段數(shù)?? q此次詢問?? 求出? l 到 r 的? 最大值 和最小值的

?

View Code
          #include<cstdio>
          
            

#include
          
          <cstring>
          
            

#include
          
          <iostream>
          
            

#include
          
          <algorithm>
          
            

#include
          
          <
          
            set
          
          >
          
            

#include
          
          <map>
          
            

#include
          
          <queue>
          
            

#include
          
          <vector>
          
            

#include
          
          <
          
            string
          
          >


          
            #define
          
           Min(a,b) a<b?a:b


          
            #define
          
           Max(a,b) a>b?a:b


          
            #define
          
           CL(a,num) memset(a,num,sizeof(num));


          
            #define
          
           maxn  60000


          
            #define
          
           inf 9999999




          
            #define
          
            mod   9973


          
            #define
          
           ll  long long


          
            using
          
          
            namespace
          
          
             std;


          
          
            int
          
           dp1[maxn][
          
            30
          
          ],dp2[maxn][
          
            30
          
          
            ],a[maxn];


          
          
            int
          
          
             n,m;


          
          
            void
          
          
             RMQ_init()

{

    
          
          
            int
          
           temp = 
          
            0
          
          
            ,i,j,s;

    
          
          
            while
          
          ( 
          
            1
          
          << temp < n)temp++
          
            ;



    
          
          
            for
          
          (i = 
          
            0
          
          ;i <= n; ++i)dp1[i][
          
            0
          
          ] = dp2[i][
          
            0
          
          ] =
          
             a[i];



    
          
          
            for
          
          (i = 
          
            1
          
          ; i <= temp ; ++
          
            i)

    {

         s 
          
          = 
          
            1
          
           << (i-
          
            1
          
          
            );

        
          
          
            for
          
          (j = 
          
            0
          
          ; j + s <= n;++
          
            j)

        {

             dp1[j][i] 
          
          = max(dp1[j][i-
          
            1
          
          ],dp1[j + s][i-
          
            1
          
          
            ]);

             dp2[j][i] 
          
          = min (dp2[j][i-
          
            1
          
          ],dp2[j + s][i - 
          
            1
          
          
            ]);

        }

    }

}


          
          
            int
          
          
            get
          
           (
          
            int
          
           l,
          
            int
          
          
             r)

{

    
          
          
            int
          
           k = r - l + 
          
            1
          
          
            ;

    
          
          
            int
          
           tmp = 
          
            0
          
          
            ;





    
          
          
            while
          
          (
          
            1
          
           << tmp < k ) tmp++
          
            ;

    tmp
          
          --
          
            ;

    
          
          
            int
          
           s = 
          
            1
          
           <<
          
             tmp;

    
          
          
            int
          
           mx = max(dp1[l][tmp],dp1[r + 
          
            1
          
           -
          
             s][tmp]);

    
          
          
            int
          
           mi = min(dp2[l][tmp],dp2[r + 
          
            1
          
           -
          
            s ][tmp]);



    
          
          
            return
          
           mx -
          
             mi ;



}


          
          
            int
          
          
             main()

{

    
          
          
            int
          
          
             i, l,r;

    
          
          
            while
          
          (scanf(
          
            "
          
          
            %d%d
          
          
            "
          
          ,&n,&m)!=
          
            EOF)

    {

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

        scanf(
          
          
            "
          
          
            %d
          
          
            "
          
          ,&
          
            a[i]);



        RMQ_init();



        
          
          
            while
          
          (m--
          
            )

        {

            scanf(
          
          
            "
          
          
            %d%d
          
          
            "
          
          ,&l,&
          
            r);

            
          
          
            int
          
           ans = 
          
            get
          
          
            (l ,r);

           printf(
          
          
            "
          
          
            %d\n
          
          
            "
          
          
            ,ans);



        }

    }



}
          
        

?

?

?

?

?

RMQ 詳解及 題目


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 成人久久18免费游戏网站 | 91精品国产91久久久久久麻豆 | 久久精品国产亚洲高清 | 热久久网站 | 啪啪色视频 | 国产在线播放成人免费 | 99精品免费观看 | 国产欧美一区二区三区免费 | 久久综合视频网站 | 91九色首页 | 国产精品欧美亚洲区 | 激情综合网色播五月 | 国产免费一级高清淫日本片 | 国产精品香蕉一区二区三区 | 成人午夜影视全部免费看 | 国产美女久久久久久久久久久 | 久久99国产精品 | 欧美午夜视频 | 久久精品国产一区 | 不卡伦理 | 欧美日韩高清一区 | 色婷婷影视 | 欧美精品日本一级特黄 | 五月婷花 | 五月婷婷激情六月 | 国产精品国内免费一区二区三区 | 91免费国产在线观看尤物 | 波多野结衣一区二区三区四区 | 一级毛片免费毛片一级毛片免费 | 久久99精品久久久久久国产越南 | 日韩www视频| 2020亚洲欧美日韩在线观看 | 国产高清国产专区国产精品 | 性新婚a大黄毛片 | 99在线精品免费视频九九视 | 奇米影视88 | 免费二区 | 欧美日韩在线观看免费 | 国产精选一区二区 | 国产精品嫩草影院99av视频 | 日本一区二区三区在线 观看网站 |