BZOJ 2821 作詩 (分塊)

2021-08-09 10:54:08 字數 2353 閱讀 1328

問題描述

神犇sjy虐完heoi之後給傻×lyd出了一題:

shy是t國的公主,平時的一大愛好是作詩。

由於時間緊迫,shy作完詩之後還要虐oi,於是shy找來一篇長度為n的文章,閱讀m次,每次只閱讀其中連續的一段[l,r],從這一段中選出一些漢字構成詩。因為shy喜歡對偶,所以shy規定最後選出的每個漢字都必須在[l,r]裡出現了正偶數次。而且shy認為選出的漢字的種類數(兩個一樣的漢字稱為同一種)越多越好(為了拿到更多的素材!)。於是shy請lyd安排選法。

lyd這種傻×當然不會了,於是向你請教……

問題簡述:n個數,m組詢問,每次問[l,r]中有多少個數出現正偶數次。

輸入格式

輸入第一行三個整數n、c以及m。表示文章字數、漢字的種類數、要選擇m次。

第二行有n個整數,每個數ai在[1, c]間,代表乙個編碼為ai的漢字。

接下來m行每行兩個整數l和r,設上乙個詢問的答案為ans(第乙個詢問時ans=0),令l=(l+ans)mod n+1, r=(r+ans)mod n+1,若l>r,交換l和r,則本次詢問為[l,r]。

輸出格式

輸出共m行,每行乙個整數,第i個數表示shy第i次能選出的漢字的最多種類數。

樣例輸入

5 3 5

1 2 2 3 1

0 4

1 2

2 2

2 3

3 5

樣例輸出

2

0 0 0 1

提示

1<=n,c,m<=10^5

首先,如果

l ,

r在同一塊,那麼暴力列舉每乙個位置,算出答案。然後考慮不在同一塊時。

注意到為了算出答案,需要知道每種顏色出現的次數,但是每個位置去算肯定會超時,注意到詢問可以分成三個部分,

l 所在的塊,

r所在的塊,和他們中間的塊,那麼如果知道了中間所有塊中,出現了正偶數次的數有多少個,同時知道了

l ,

r所在塊中出現的顏色在整個詢問區間中出現的次數,那麼就可以算出答案。

首先處理中間塊的出現了正偶數次的數有多少。顯然需要預處理。

那麼令f[i

][j]

表示從第

i 塊到第

j塊的答案,那麼這個可以在o(

nn−−

√ 內處理出來,具體實現可以參考**。

然後考慮如何知道

l ,

r所在塊中的數字在整個區間中出現的次數,同樣分成兩部分來考慮,一部分是中間塊的出現次數,另一部分是

l ,

r所在塊的出現次數。後者每次暴力列舉即可,考慮前者,考慮字首和。

那麼令g[i

][j]

表示[1

,i] 塊中數字

j 出現的次數,那麼同樣可以o(

nn−−

√)處理出來,處理方法見**。

於是就可以處理不在同一塊的情況了,先令su

m 為中間塊的答案,每次只需要看

l ,

r所在塊中出現的數字在中間塊中出現的次數和在全區間出現次數的關係對su

m 進行修改即可。

**:

#include

#include

#include

#define m 100005

using namespace std;

int n,c,m,s,n,ans,a[m],f[333][333],g[333][m],cnt[m],t[m],q[m],id[m];

int gs(int

x,int

y,int t)

return sum;

}if(l+1

<=r-1)sum=f[l+1][r-1];

for(i=x;i<=l*s&&i<=n;i++)

for(i=y;i>(r-1)*s;i--)

return sum;

}int main()

memset(cnt,0,sizeof(cnt));

for(i=1;i<=n;i++)//預處理g[i][j]

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

}

bzoj2821 作詩 Poetize 分塊

description 神犇sjy虐完heoi之後給傻 lyd出了一題 shy是t國的公主,平時的一大愛好是作詩。由於時間緊迫,shy作完詩 之後還要虐oi,於是shy找來一篇長度為n的文章,閱讀m次,每次只閱讀其中連續的一段 l,r 從這一段中選出一 些漢字構成詩。因為shy喜歡對偶,所以shy規...

BZOJ2821 作詩 Poetize 分塊

神犇sjy虐完heoi之後給傻 lyd出了一題 shy是t國的公主,平時的一大愛好是作詩。由於時間緊迫,shy作完詩之後還要虐oi,於是shy找來一篇長度為n的文章,閱讀m次,每次只閱讀其中連續的一段 l,r 從這一段中選出一些漢字構成詩。因為shy喜歡對偶,所以shy規定最後選出的每個漢字都必須在...

BZOJ 2821 作詩 Poetize 分塊

非常神的一道分塊的題 記得剛進bz坑的時候看到這道題50秒特別驚奇0.0 然後我就作死去交了個死迴圈0.0 看了非常多題解 都沒看懂 最後還是把零碎的思想硬拼到一起才寫完0.0 我們首先分塊 然後預處理一些東西 首先是從第i塊到第j塊的答案 這個我們從第i塊第乙個點開始向右掃 開乙個陣列記錄每乙個數...