NKOJ 2751 蒲公英(分塊)

2021-08-14 13:53:28 字數 2958 閱讀 9639

問題描述

輸入格式

第一行兩個整數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行。每行乙個整數,表示每次詢問的結果。

樣例輸入

6 3

1 2 3 2 1 2

1 5

3 6

1 5

樣例輸出

1 2 1

提示

對於 20% 的資料,保證1<=n,m<=3000。

對於 100% 的資料,保證1<=n<=40000,1<=m<=50000,1<=ai<=10^9

區間眾數問題,分塊的經典解法,兩種處理方法

做法一: 分成n

13n 13

塊,預處理b[

i][j

] b[i

][j]

表示第i i

塊到第j' role="presentation" style="position: relative;">j

j塊的資訊,維護每個數出現的次數,並記錄區間眾數。

查詢的時候,先找到覆蓋的最大整塊區間[l

,r] [l,

r]

將b[l][r

] b[l

][r]

複製出來,然後將兩邊剩下的數暴力插入。

複雜度o(n

53) o(n

53

)做法二: 分成n

−−√ n

塊,預處理a[

i][j

] a[i

][j]

表示第i i

塊到第j' role="presentation" style="position: relative;">j

j塊中的眾數,並記錄眾數的出現次數

查詢的時候,同樣找到區間[l

,r] [l,

r]

,答案只可能是a[

l][r

] a[l

][r]

或兩側剩下的數,列舉兩側剩下的數,然後查詢一下他在區間中出現的次數,更新答案即可。

關於查詢乙個數在區間中的出現次數,可以用vector記下每個數出現位置然後二分查詢,複雜度o(

nn−−

√log

2n) o(n

nlog

2n

)或者預處理s[

i][j

][k]

s [i

][j]

[k

],表示第

i i

塊中,前

j' role="presentation" style="position: relative;">j

j個位置,數字

k k

出現次數,ss

[i][

k]' role="presentation" style="position: relative;">ss[

i][k

]ss[

i][k

],表示前

i i

塊中,數字

k' role="presentation" style="position: relative;">k

k出現的次數,然後查詢的時候就可以直接用了(

s s

可以不用處理,每次暴力跑一邊兩邊剩下的數就行了),由於每塊最多

n' role="presentation" style="position: relative;">n−−

√n個數,因此預處理的時空複雜度都是o(

nn−−

√)o (n

n)

,總時間複雜度也是o(

nn−−

√)o (n

n)

做法一**:

#include

#include

#include

#include

#include

#define n 50005

using

namespace

std;

struct node

}c[40][40],tmp;

int n,m,a[n],b[n],id[n],lp[n],rp[n],s,cnt;

int gs(int l,int r)

x=id[l]+1;y=id[r]-1;

p=c[x][y].a;q=c[x][y].b;

for(i=l;ifor(i=rp[y]+1;i<=r;i++)c[x][y].ins(a[i]);

k=c[x][y].a;c[x][y].a=p;c[x][y].b=q;

for(i=l;ifor(i=rp[y]+1;i<=r;i++)c[x][y].del(a[i]);

return b[k];

}int main()

for(i=1;i<=cnt;i++)

for(j=i;j<=cnt;j++)

for(k=lp[i];k<=rp[j];k++)c[i][j].ins(a[k]);

for(i=1;i<=m;i++)

}

蒲公英 分塊

在鄉下的小路旁種著許多蒲公英,而我們的問題正是與這些蒲公英有關。為了簡化起見,我們把所有的蒲公英看成乙個長度為 n 的序列a1,a2,an,其中ai為乙個正整數,表示第 i 棵蒲公英的種類編號。而每次詢問乙個區間 l,r 你需要回答區間裡出現次數最多的是哪種蒲公英,如果有若干種蒲公英出現次數相同,則...

分塊 蒲公英

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 加上中間完整整塊對這些顏色的貢獻...