洛谷小B的詢問(莫隊)

2021-08-21 03:39:51 字數 1583 閱讀 8664

p2709 小b的詢問

題目描述

小b有乙個序列,包含n個1~k之間的整數。他一共有m個詢問,每個詢問給定乙個區間[l…r],求sigma(c(i)^2)的值,其中i的值從1到k,其中c(i)表示數字i在[l…r]中的重複次數。小b請你幫助他回答詢問。

輸入輸出格式

輸入格式:

第一行,三個整數n、m、k。

第二行,n個整數,表示小b的序列。

接下來的m行,每行兩個整數l、r。

輸出格式:

m行,每行乙個整數,其中第i行的整數表示第i個詢問的答案。

輸入輸出樣例

**輸入樣例#1: **

6 4 3

1 3 2 1 1 3

1 42 6

3 55 6

**輸出樣例#1: **69

52說明

對於全部的資料,1<=n、m、k<=50000

這是本蒟蒻第一次寫莫隊演算法,但是由於題目太水,直接過掉。

這裡簡單說一下莫隊演算法吧。

莫隊演算法其實就是一種優雅的暴力,對於隨機的資料,常規的暴力其實表現是不錯的,但是常規的暴力並沒有複雜度的保證,那麼我們知道,常規的暴力最壞情況是o(1

)o(1)

o(1)

預處理,o(n

)o(n)

o(n)

查詢,原因是詢問區間的左右端點的移動次數沒***,那麼為了使它們的移動次數***,我們要借用分塊的思想,將詢問的左端點分塊,讓塊的編號作為第一關鍵字,右端點作為第二關鍵字排序,這樣在塊內部每次移動最多o(s

qrt(

n)

)o(sqrt(n))

o(sqrt

(n))

,塊與塊之間每次最多也移動o(s

qrt(

n)

)o(sqrt(n))

o(sqrt

(n))

,因此我們處理詢問的複雜度就有了保障。總時間複雜度為o(n

∗sqr

t(n)

)o(n*sqrt(n))

o(n∗sq

rt(n

))。

這題的**:

#include#define n 50005

using namespace std;

int n,m,k,sig,a[n],sum[n],cnt[n],tl=0,tr=0,ans=0;

inline int read()

struct nodeq[n];

inline bool cmp(node a,node b)

while(trqr)

sum[q[i].id]=ans-1;

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

return 0;

}

洛谷2709 小B的詢問(莫隊)

小b有乙個序列,包含n個1 k之間的整數。他一共有m個詢問,每個詢問給定乙個區間 l.r 求sigma c i 2 的值,其中i的值從1到k,其中c i 表示數字i在 l.r 中的重複次數。小b請你幫助他回答詢問。第一行,三個整數n m k。第二行,n個整數,表示小b的序列。接下來的m行,每行兩個整...

洛谷2709 小B的詢問(莫隊模板題)

點此看題面 大致題意 有乙個長度為n nn的序列,每個數字在1 k 1 sim k 1 k之間,有m mm個詢問,每個詢問給你乙個區間,讓你求出 i 1kc i 2 sum k c i 2 i 1k c i 2,其中c i c i c i 表示數字i ii在該區間內的出現次數。莫隊演算法 顯然,這題...

洛谷P2709 小B的詢問 莫隊

按根下n分個塊,對詢問區間雙關鍵字排序,若不在乙個塊裡按左端點排序,若在按右端點排序,然後掃一遍統計答案 考慮每次移動指標後答案的改變 分為四種情況 分別是l,r指標在查詢區間的l和r的左邊還是右邊,都討論一下 每種情況該怎麼做在紙上畫畫就明白了。沒必要特意記 include include inc...