BZOJ 3110 Zjoi2013 K大數查詢

2022-05-08 05:42:10 字數 2291 閱讀 9525

有n個位置,m個操作。操作有兩種,每次操作如果是1 a b c的形式表示在第a個位置到第b個位置,每個位置加入乙個數c

如果是2 a b c形式,表示詢問從第a個位置到第b個位置,第c大的數是多少。

第一行n,m

接下來m行,每行形如1 a b c或2 a b c

輸出每個詢問的結果

2 51 1 2 1

1 1 2 2

2 1 1 2

2 1 1 1

2 1 2 312

1【樣例說明】

第乙個操作 後位置 1 的數只有 1 , 位置 2 的數也只有 1 。 第二個操作 後位置 1

的數有 1 、 2 ,位置 2 的數也有 1 、 2 。 第三次詢問 位置 1 到位置 1 第 2 大的數 是

1 。 第四次詢問 位置 1 到位置 1 第 1 大的數是 2 。 第五次詢問 位置 1 到位置 2 第 3

大的數是 1 。‍

n,m<=50000,n,m<=50000

a<=b<=n

1操作中abs(c)<=n

2操作中c<=maxlongint

正解:cdq分治

解題報告:

聽說這是一道cdq分治模板題,於是跑來圍觀。

cdq分治的處理十分神奇,一般用於處理有修改、有查詢的可離線的題目。  

這道題目就是每次在一段位置都插入乙個數,並動態詢問問區間內第幾大的數是多少。我們可以考慮cdq分治。首先二分乙個答案x,x指的是詢問的答案(題意中說了只能是1到n),我們就對於一下當前這一段的處理序列中,先依次處理,碰到詢問就考慮是否可行。如果對於乙個詢問,發現當前的x之下查詢的ans大於那個值,說明答案更小,所以要放到左邊去遞迴處理,但是同時記得,把詢問的值減掉查詢出的ans,表示這一段肯定比它大,先減掉。至於查詢的話,區間修改、區間查詢,可以考慮用樹狀陣列。

總的來說,我對cdq分治體會還是挺深,但是還是不夠熟練,需要多加練習。

1

//it is made by jump~

2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include

13using

namespace

std;

14 typedef long

long

ll;15

const

int maxm = 50011;16

intn,m;

17int

tmp[maxm],ans[maxm];

18ll c1[maxm],c2[maxm];

19bool

pd[maxm];

20struct

aska[maxm],zuo[maxm],you[maxm];

2324 inline int

getint()

2530

31 inline void

add(ll x,ll y)37}

3839

inline ll sum(ll x)

4445 inline void cdq(int askl,int askr,int l,int

r)//

答案唯一確定了

48int mid=(l+r+1)/2;49

int nowl=0,nowr=0

; ll now;

50for(int i=askl;i<=askr;i++)

55else60}

61for(int i=askl;i<=askr;i++) if(a[i].id==1 && a[i].val>=mid) add(a[i].l,-1),add(a[i].r+1,1); //

清空62

for(int i=1;i<=nowl;i++) a[askl+i-1]=zuo[i];

63for(int i=1;i<=nowr;i++) a[askl+nowl+i-1]=you[i];

64 cdq(askl,askl+nowl-1,l,mid-1

);65 cdq(askl+nowl,askr,mid,r);66}

6768 inline void

work()

71 cdq(1,m,1

,n);

72for(int i=1;i<=m;i++) if(pd[i]) printf("

%d\n

",ans[i]);73}

7475

intmain()

76

BZOJ 3110 Zjoi2013 K大數查詢

title bzoj 3110 zjoi2013 k大數查詢 categories bzoj date 2016 2 3 00 00 00 tags 樹套樹,整體二分 有n個位置,m個操作。操作有兩種,每次操作如果是1 a b c的形式表示在第a個位置到第b個位置,每個位置加入乙個數c 如果是2 a...

BZOJ 3110 Zjoi2013 K大數查詢

title bzoj 3110 zjoi2013 k大數查詢 categories bzoj date 2016 2 3 00 00 00 tags 樹套樹,整體二分 有n個位置,m個操作。操作有兩種,每次操作如果是1 a b c的形式表示在第a個位置到第b個位置,每個位置加入乙個數c 如果是2 a...

BZOJ3110 Zjoi2013 K大數查詢

整體二分 樹狀陣列 這道題和某題類似 整體二分,每次二分乙個值,因為是求第k大,比二分值大的在 l r 區間 1,詢問就問這個區間的數,如果數量大於k,說明實際答案大於二分值,下放右區間,否則下放左區間,k減去詢問的值 因為後面不會再考慮mid r的值 把區間加操作也按照權值兩邊下放,每次詢問完答案...