點此看題面
大致題意:演算法標籤——語文,給定乙個數列,多組詢問,每次詢問乙個區間內的眾數出現的次數。
這道題的演算法應該是莫隊。
我們可以用\(cnt\)陣列記錄下每個數出現的次數(注意要先離散化),用\(tot\)陣列記錄下每個數在\(cnt\)陣列中的出現次數,並用\(ans\)記錄答案。
當我們要加入乙個新數\(x\)的時候,如果加入前的\(cnt_x=ans\),則加入後的\(cnt_x\)肯定大於\(ans\),因此將\(ans\)加\(1\)。
當我們要刪除乙個數\(x\)的時候,如果刪除前\(cnt_x=ans\)且\(tot_=1\),則刪除該元素後就沒有元素的出現個數為\(ans\)了,因此將\(ans\)減\(1\)。
這樣就可以了。
#include#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)<0?-(x):(x))
#define ll long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define fsize 100000
#define tc() (finnow==finend&&(finend=(finnow=fin)+fread(fin,1,fsize,stdin),finnow==finend)?eof:*finnow++)
#define pc(ch) (foutsizey.r);
}inline int find(int x)//求出離散化後的值
//將區間右邊界增加
while(l>q[i].l) //將區間的左邊界減小
while(r>q[i].r) //將區間的右邊界減小
while(lres[q[i].pos]=ans;//用res陣列儲存答案
}for(i=1;i<=q;++i) (res?pc('-'):0),write(res[i]),pc('\n');//按讀入的順序輸出答案
return fwrite(fout,1,foutsize,stdout),0;
}
莫隊 洛谷 P3709 大爺的字串題
給你乙個字串a,每次詢問一段區間的貢獻 貢獻定義 每次從這個區間中隨機拿出乙個字元x,然後把x從這個區間中刪除,你要維護乙個集合s 如果s為空,你rp減1 如果s中有乙個元素不小於x,則你rp減1,清空s 之後將x插入s 由於你是大爺,平時做過的題考試都會考到,所以每次詢問你搞完這段區間的字元之後最...
luogu3709 大爺的字串題
題目鏈結 一天做到兩道這種題目描述如此神仙的題也是夠了。真鍛鍊語文能力。題目的意思其實就是,給你乙個序列,然後每次詢問乙個區間。使得盡量按照嚴格上公升的順序從這個區間內取數。如果當前取得數字小於等於前面的其中乙個,就讓rp 然後重新開始記錄。問rp最多可以是多少。思考一下可以發現,其實就是求區間內眾...
P3709 大爺的字串題
p3709 傳送門 lxl出的語文題 其實轉化一下就是求將當前區間最少拆分成多少個嚴格單調上公升序列 可不連續 再轉化一下就是求區間內的眾數個數 本來求眾數的套路是主席樹 二分 這樣在刪除時僅當 sum cnt dat pos 1 時才減少 cur include using namespace s...