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