bzoj3110 Zjoi2013 K大數查詢

2022-05-21 14:00:13 字數 1323 閱讀 3892

(題目鏈結)

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

整體二分入門題。

對於一段操作,我們二分乙個答案mid,將修改操作中加入的數c大於等於mid的操作執行(用樹狀陣列維護一段區間中大於等於mid的數的個數)。然後對於詢問判斷c是否大於等於已經加入的大於等於mid的數的個數,然後不斷遞迴下去。

第k大的二分寫的我心慌,整個都是反過來的。。

// bzoj3110

#include#include#include#include#include#include#define ll long long

#define mod 100000000

#define inf 2147483640

#define pi acos(-1.0)

#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);

using namespace std;

const int maxn=50010;

struct data a[maxn],tr[maxn],tl[maxn];

ll c1[maxn],c2[maxn];

int ans[maxn],n,m;

int lowbit(int x)

ll query(int x)

void add(int x,int val)

void solve(int l,int r,int l,int r)

int mid=(l+r+1)>>1,ll=0,rr=0,fl=0,fr=0;

for (int i=l;i<=r;i++)

else

} for (int i=l;i<=r;i++) if (a[i].t==1 && a[i].k>=mid) add(a[i].l,-1),add(a[i].r+1,1);

for (int i=1;i<=ll;i++) a[l+i-1]=tl[i];

for (int i=1;i<=rr;i++) a[l+ll+i-1]=tr[i];

if (fl) solve(l,l+ll-1,l,mid-1);

if (fr) solve(l+ll,r,mid,r);

}int main()

solve(1,m,1,n);

for (int i=1;i<=tot;i++) printf("%d\n",ans[i]);

return 0;

}

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