蒲公英 分塊

2022-02-15 23:28:26 字數 1791 閱讀 9298

在鄉下的小路旁種著許多蒲公英,而我們的問題正是與這些蒲公英有關。

為了簡化起見,我們把所有的蒲公英看成乙個長度為 n 的序列a1,a2,…,an,其中ai為乙個正整數,表示第 i 棵蒲公英的種類編號。

而每次詢問乙個區間 [l,r] ,你需要回答區間裡出現次數最多的是哪種蒲公英,如果有若干種蒲公英出現次數相同,則輸出種類編號最小的那個。

第一行兩個整數n,m,表示有 n 株蒲公英,m 次詢問。

接下來一行 n 個空格隔開的整數ai,表示蒲公英的種類。

再接下來 m 行每行兩個整數l0,r0,我們令上次詢問的結果為 x(如果這是第一次詢問,則 x=0)。

令l=(l0+x-1) mod n+1,r=(r0+x-1) mod n+1,如果l>r,則交換l,r。

最終的詢問區間為[l,r]。

輸出 m 行。

每行乙個整數,表示每次詢問的結果。

1≤n≤40000,

1≤m≤50000,

1≤ai≤109

6 3 

1 2 3 2 1 2

1 5

3 6

1 5

1 

2 1

先離散化+預處理 o(nt + nlongn), t為總共的分塊數, len為塊的大小

當 r - l + 1 >= len * 2 - 1, 則l-r內必有乙個整塊(包含邊界)

1.如果不想麻煩,可以對 r - l + 1 < len * 2 - 1 直接暴力,從 l 到到r,按書上二分方法去查詢在l-r直接a[i]的個數,暴力找答案

2.l為塊左邊界 (l % len == 1),r為右邊界(r % len == 0 || r == n(最後不足一塊)),預處理已經知道答案

3.l為塊左邊界,找到r 所在塊的左邊界 rl,預處理知道答案 l-(lr - 1), 暴力rl - r

3.r為塊右邊界, 同上

4.分別找 rl 和 lr,預處理知道 (lr + 1) - (rl - 1)的答案,暴力l - rl、 rl - r即可

大概複雜度為 o(nt + m *n * log n / t), 求導 t = (m * n * log(n))^ (1/3)

#include #define find(x) ((x - 1) / len + 1)

#define wide(l,r) (r - l + 1)

using namespace std;

const int maxn = 4e4 + 5;

const int maxt = 3130;

int len, t, n, m, a[maxn], b[maxn], f[maxt][maxt], tax[maxn], x;

vectorve[maxn];

void init()

for (int i = 1; i <= t; ++ i, memset(tax, 0, sizeof tax))

if (j % len == 0 || j == n) f[i][find(j)] = mid;}}

}int get(int l, int r, int k)

int work(int cnt, int l, int r, int ll, int rr)

}return cnt;

}int main()

else if (r % len == 0)

else

printf("%d\n", b[x]);

}return 0;

}

分塊 蒲公英

include include include include define maxn 40005 using namespace std int rd return x partition section int a maxn blk maxn sizb int tmplwb maxn 離散化的輔...

Violet 蒲公英 分塊

題解 講道理,關於區間眾數問題應該第乙個就想到分塊,可毒瘤出題人說是線段樹.qaq 考慮查詢的區間 l,r 第一種情況,我們可以考字首和以及遞推來進行預處理,查詢的時候直接呼叫即可。第二種情況,我們開乙個桶,將 2 個端點所在不完整塊進行統計,再用乙個 vector 加上中間完整整塊對這些顏色的貢獻...

Violet 蒲公英(分塊)

即使是分塊也無法簡單的合併兩個塊的資料,所以我們考慮分塊的本質 暴力,直接維護塊合併後的資訊 用 f i j 表示第i塊到第j塊這一段的眾數,那麼接下來就可以只考慮怎麼加入兩頭的數 考慮暴力求眾數的做法 記錄當前的眾數以及所有數的出現次數,如果新加入的數的出現次數大於眾數,那麼它取代原眾數成為新的眾...