ZJOI2013 K大數查詢

2021-09-11 05:35:08 字數 1427 閱讀 8695

有n個位置,m個操作。操作有兩種,每次操作如果是:

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

輸入格式:

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

輸出格式:

輸出每個詢問的結果

solution

整體二分。

假設我們現在要解決[ql,qr] 並且他們的答案(加數操作就是值)在[l,r]

二分乙個mid,我們維護乙個區間。

我們把》=mid的操作對應區間都加1

對於詢問,如果對應區間的值》=c,說明mid-r有最少c個了,那麼它的答案就在[mid,r]裡。

否則把值減去區間對應值,丟進[l,mid-1]裡。

樹狀陣列有個高階的區間加區間查寫法,維護差分和差分*i

#include#include

#include

#include

#include

#include

#define maxn 500005

using

namespace

std;

intn,m,max,t1[maxn],t2[maxn];

struct

nodeq[maxn],s[maxn];

void add(int x,int

v)int ask(int

x)

return

sum;

}void solve(int l,int r,int ql,int

qr)

int mid=l+r+1>>1

;

int p=ql;

for(int i=ql;i<=qr;i++)

else p++;

}else

}int n1=ql,n2=p;

for(int i=ql;i<=qr;i++)

else s[n1++]=q[i];

}else

else s[n2++]=q[i];}}

for(int i=ql;i<=qr;i++)q[i]=s[i];

solve(l,mid-1,ql,p-1

);solve(mid,r,p,qr);

}bool id(node a,node b)

intmain()

solve(

1,max,1

,m);

sort(q+1,q+m+1

,id);

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

}return0;

}

view code

posted @

2019-02-21 09:24

liankewei123456 閱讀(

...)

編輯收藏

ZJOI2013 K大數查詢

有n個位置,m個操作。1 a b c形式,表示在第a個位置到第b個位置,每個位置加入乙個數c 2 a b c形式,表示詢問從第a個位置到第b個位置,第c大的數是多少。區間的第k大值有一種二分的做法。二分答案mid,計算出區間內 mid的值有多少個。若數量小於c,則ans mid,否則ans mid。...

ZJOI2013 K大數查詢

點此看題 0x01 樹套樹 這道題的思路特別巧妙,樹套樹不一定要用區間線段樹套權值線段樹,還可以反過來套。我們維護乙個動態開點的權值線段樹,每個點代表權值 l,r l,r l,r 在整個區間的出現情況,套上乙個動態開點的區間線段樹,操作1 11對權值線段樹單點修改,然後對每個點的 a,b a,b a...

ZJOI2013 K大數查詢

顯然可以線段樹套線段樹。但是必須卡常。所以我採用了整體二分。注意是區間第k大,而不是第k小。然後區間轉化一下即可。有乙個剪枝的地方,就是如果這個區間已經沒有查詢的操作了,那就不用遞迴了。ac pragma gcc optimize ofast funroll all loops include de...