有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的值 把區間加操作也按照權值兩邊下放,每次詢問完答案...