BZOJ3110 Zjoi2013 K大數查詢

2021-07-23 19:03:48 字數 2067 閱讀 8948

整體二分+樹狀陣列

這道題和某題類似:

整體二分,每次二分乙個值,因為是求第k大,比二分值大的在[l

,r] 區間+1,詢問就問這個區間的數,如果數量大於k,說明實際答案大於二分值,下放右區間,否則下放左區間,k減去詢問的值(因為後面不會再考慮mid~r的值),把區間加操作也按照權值兩邊下放,每次詢問完答案要撤銷之前的區間加操作

這題學了新姿勢:樹狀陣列區間修改+區間查詢

有篇介紹樹狀陣列的blog:

樹狀陣列區間修改的大致思想是將序列查分,區間加減就變成單點修改,詢問(l

,r) 區間和的時候求su

m(r)

−sum

(l−1

) 設原序列是

a ,查分序列是

b,得 su

m(i)

=a1+

a2+.

..ai

因為ai

=b1+

b2+.

..bi

所以su

m(i)

=b1∗

i+b2

∗(i−

1)+.

..+b

i∗1=

(i+1

)∗∑j

=1ib

j−∑j

=1ij

∗bj

然後這兩個東西都可以用樹狀陣列維護

code:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define inf 110000

using namespace std;

const int maxn = 110000;

struct node

node(int a1,int a2,ll a3,int a4,int a5)

}a[maxn],b[maxn],c[maxn]; int num;

ll s[maxn],si[maxn];

int ans[maxn];

int n,m;

int lowbit(int

x)void update(ll *tr,int

x,ll c)}

ll q(ll *tr,int x)return ret;}

void add(int l,int r,ll c)

ll query(int l,int r)

void solve(int lp,int rp,int

lc,int rc)

int mid=(lc+rc)>>1; int bn=0,cn=0;

for(int i=lp;i<=rp;i++)

else b[++bn]=a[i];

}else}}

for(int i=lp;i<=rp;i++)

if(a[i].s==0&&a[i].c>mid) add(a[i].l,a[i].r,-1);

for(int i=1;i<=bn;i++)a[lp+i-1]=b[i];

for(int i=1;i<=cn;i++)a[lp+bn+i-1]=c[i];

solve(lp,lp+bn-1,lc,mid);

solve(lp+bn,rp,mid+1,rc);

}int main()

else

}for(int i=1;i<=m;i++)ans[i]=-inf-1;

solve(1,num,-inf,inf);

for(int i=1;i<=m;i++)if(ans[i]!=-inf-1)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大數查詢

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