UVA 11235 遊程編碼 ST演算法

2021-09-08 10:27:16 字數 1370 閱讀 3054

題目大意:給定乙個公升序序列,有q次詢問,每次詢問(l,r)出現最多的值的次數。

解題思路

非常麻煩的題目。儘管一眼就能看出來是個rmq。

關鍵在於如何轉化為rmq。

首先對序列進行遊程編碼,壓縮成pos段。

編碼的同時用num[i]記錄當前點在段中編號,lb[i]記錄在當前段的左邊界,更新code[pos](當前段的容量)

編碼之後o(n)掃一遍,用num[i]、code[num[i]]和lb[i]搞出在當前段的右邊界rb[i]。

則q(l,r)的時候有以下幾種情況:

①如果num[l]=num[r],則說明l,r在同一段,ans=r-l+1。

②如果num[l]≠num[r],則說明l,r不在同一段,

則整個(l,r)被劃分成三段:(l,rb[l]-l+1)這些元素在同乙個段中,(num[l]+1,num[r]-1)前提是num[l]+1<=num[r]-1,(r-lb[r]+1,r)這些元素在同乙個段中。

由於左右段都在同一段中,max元素個數即可。中間這段混合了多個完整的段,直接st即可,注意st初始化的是段的容量。

#include "

cstdio

"#include

"cstring

"#include

"iostream

"using

namespace

std;

#define maxn 100000

#define maxp 20

intrmq[maxn][maxp],n,q,w,l,r,code[maxn],num[maxn],lb[maxn],rb[maxn];

template

inline

bool read(t &ret)

void

st()

int query(int l,int

r)int q(int l,intr)}

intmain()

else

num[i]=pos; //

當前點段編號

}

for(int i=1;i<=n;i++) rb[i]=lb[i]+code[num[i]]-1; //

右邊界 n=pos;

st();

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

}}

2809497

neopenx

uva 11235

accepted

0 kb

182 ms

c++ 4.8.2

1827 b

2014-10-03 18:18:58

題目1123 採藥

題目描述 辰辰是個很有潛能 天資聰穎的孩子,他的夢想是稱為世界上最偉大的醫師。為此,他想拜附近最有威望的醫師為師。醫師為了判斷他的資質,給他出了乙個難題。醫師把他帶到個到處都是草藥的山洞裡對他說 孩子,這個山洞裡有一些不同的草藥,採每一株都需要一些時間,每一株也有它自身的價值。我會給你一段時間,在這...

11 23 原子操作

為了編譯android src,把gcc 版本版本降到4.3 後來學習核心模組 原子操作,寫了乙個測試模組,可以順利make,有個warning mcount undefined.接著又測試下之前寫好的模組,也出現了相同的錯誤.在網上找了好久,沒有發現此問題的解決辦法,仔細回憶機器環境的變化就是gc...

早安,努力 11 23

乙個人一旦踏上了成熟的道路,他就不會再有所失,他只會有所獲。直到那個時刻也降臨於他,他將發現鳥籠開著,於是帶著最後的心跳逃離充滿缺陷的世界。早安,努力 朝聖者之歌摘錄 這學期是和老大合作的最後乙個學期,想起來心有不捨,以後可能就再也遇不到這樣的老師了。包括我的大學 來之前一直嫌棄 來了之後 遇到了很...