luogu3709 大爺的字串題

2022-04-10 05:42:27 字數 1282 閱讀 8159

題目鏈結

一天做到兩道這種題目描述如此神仙的題也是夠了。真鍛鍊語文能力。

題目的意思其實就是,給你乙個序列,然後每次詢問乙個區間。使得盡量按照嚴格上公升的順序從這個區間內取數。如果當前取得數字小於等於前面的其中乙個,就讓rp--,然後重新開始記錄。問rp最多可以是多少。

思考一下可以發現,其實就是求區間內眾數出現的次數。

原因如下:

如果有相等的數字,那麼這些數字是無法避免rp--的。既然無論如何都要減了,那麼就要考慮如何讓他減得更有價值。

比如說有一段序列:1 1 1 2 2 5 5 6 7 8

現在1 和 2都是有多個,顯然按照下面的順序取數是最優秀的:

1 2 5 6 7 8 1 2 5 1

這樣減掉的rp其實就是眾數1出現的次數。

所以這道題就是詢問區間內眾數出現的次數了。可以用莫隊來實現。

用cnt[i]來表示i這個數字出現的次數(需要先離散化)。t[i]表示出現次數為i的數的個數。

在從乙個區間向另乙個區間轉移時,方法很顯然。具體見**

/*

* @author: wxyww

* @date: 2018-12-17 20:07:20

* @last modified time: 2018-12-17 20:40:37

*/#include#include#include#include#include#include#include#includeusing namespace std;

typedef long long ll;

const int n = 200000 + 10;

mapma;

ll read()

while(c>='0'&&c<='9')

return x*f;

}int a[n],cnt[n],ls[n],anss[n];

int ans,l,r,belong[n],t[n];

struct node q[n];

bool cmp(node x,node y)

void update(int pos,int c)

cnt[a[pos]] += c;

t[cnt[a[pos]]]++;

if(cnt[a[pos]] > ans) ans = cnt[a[pos]];

}int main()

for(int i = 1;i <= m;++i) printf("%d\n",-anss[i]);

return 0;

}

烟花易冷,人事易分。

P3709 大爺的字串題

p3709 傳送門 lxl出的語文題 其實轉化一下就是求將當前區間最少拆分成多少個嚴格單調上公升序列 可不連續 再轉化一下就是求區間內的眾數個數 本來求眾數的套路是主席樹 二分 這樣在刪除時僅當 sum cnt dat pos 1 時才減少 cur include using namespace s...

P3709 大爺的字串題(50分)

在那遙遠的西南有一所學校 被和諧部分 然後去參加該省省選虐場 然後某蒟蒻不會做,所以也出了乙個字串題 給你乙個字串a,每次詢問一段區間的貢獻 貢獻定義 每次從這個區間中隨機拿出乙個字元x,然後把x從這個區間中刪除,你要維護乙個集合s 如果s為空,你rp減1 如果s中有乙個元素不小於x,則你rp減1,...

P3709 大爺的字串題 腦子 莫隊

簡化題意 區間眾數出現次數?為什麼?原因是,貪心的想,我們要劃分成盡量少的嚴格遞增序列,這樣rp掉的最少。設區間眾數出現次數為 x 那我們至少要分成 x 段嚴格上公升序列。include include include include include define r register int us...