有n個位置,m個操作。操作有兩種,每次操作是:
2 a b c:表示詢問從第a個位置到第b個位置,第c大的數是多少。
演算法見注釋
#include#define int long long
using namespace std;
const int n=5e4+5;
int n,m,qqq;
struct data
};data q[n];
int ans[n];
struct bit
int pre(int pos)
};bit d,dm;
void add(int l,int r,int v)
int pre(int pos)
int sum(int l,int r)
data q1[n],q2[n];
void solve(int l,int r,int l,int r)
int mid=(l+r)>>1,l1=0,l2=0;
for(int i=l;i<=r;i++) else
}for(int i=1;i<=l2;i++)if(q2[i].t==1)add(q2[i].a,q2[i].b,-1);//還原
for(int i=1;i<=l1;i++)q[l+i-1]=q1[i];
for(int i=1;i<=l2;i++)q[l+l1+i-1]=q2[i];
solve(l,l+l1-1,l,mid);
solve(l+l1,r,mid+1,r);
}signed main()
/* * 考慮整體二分。二分答案後,問題轉化為
* - 查詢比mid大的數
* - 區間新增數
* 整體二分是要求貢獻獨立的,因此在二分的過程中只考慮跨區間的貢獻,並且
* 必須全部統計完
*/
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大數查詢
有n個位置,m個操作。操作有兩種,每次操作如果是 2 a b c 表示詢問從第a個位置到第b個位置,第c大的數是多少。輸入格式 第一行n,m接下來m行,每行形如1 a b c或2 a b c 輸出格式 輸出每個詢問的結果 solution 整體二分。假設我們現在要解決 ql,qr 並且他們的答案 加...
ZJOI2013 K大數查詢
點此看題 0x01 樹套樹 這道題的思路特別巧妙,樹套樹不一定要用區間線段樹套權值線段樹,還可以反過來套。我們維護乙個動態開點的權值線段樹,每個點代表權值 l,r l,r l,r 在整個區間的出現情況,套上乙個動態開點的區間線段樹,操作1 11對權值線段樹單點修改,然後對每個點的 a,b a,b a...