P3332 ZJOI2013 K大數查詢

2022-05-03 09:42:06 字數 2477 閱讀 7576

有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

輸出格式:

輸出每個詢問的結果

輸入樣例#1:

2 5

1 1 2 1

1 1 2 2

2 1 1 2

2 1 1 1

2 1 2 3

輸出樣例#1:

1

21

【樣例說明】

第乙個操作 後位置 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

演算法一:區間線段樹+權值線段樹  

演算法二:整體二分+區間修改/詢問樹狀陣列

整體二分部分正如上文,但是本題重點在於區間修改/詢問樹狀陣列

1.單點修改+單點詢問

普通樹狀陣列即可

2.區間修改+單點詢問

考慮差分即可

我們興建乙個查分陣列來做樹狀陣列,並且將原有a陣列保留  

修改時就修改delta陣列即可

詢問就加上delta的字首和與a陣列即可

3.區間修改+區間詢問

首先依舊是引入delta陣列 delta[i]表示區間 [i, n] 的共同增量

於是修改區間 [l, r] 時修改 delta[l] 和 delta[r + 1] 即可(就是差分的思路)

查詢的時候是查詢區間 [l, r] 的和 即sum[r] - sum[l - 1] 所以現在的問題是求sum[i]

sum[i]=a[1]+....+a[i]+delta[1]*i+delta[2]*(i-1)...delta[i]*1

=sigma(a[x])+sigma(delta[x]*(i+1-x))

=sigma(a[x])+(i+1)*sigma(delta[x])-sigma(delta[x]*x)

於是維護兩個樹狀陣列delta[x]和delta[x]*x即可!

//

luogu rank1 1049ms

//@2017-03-06 14:13

#include#include

#define ll long long

#define ep if(ch==eof) return eof;

using

namespace

std;

inline

intread()

while(ch>='

0'&&ch<='9')

return x*f;

}const

int z=6e4+5

;struct

nodep[z],p1[z],p2[z];

intn,m,cnt,ans[z];

ll bit[z],bit[z];

intmx,mn;

inline

int lowbit(int

x)inline

void update(int x,int

d)inline ll ask(

intx)

void solve(int l,int r,int x,int

y)

int mid=x+y>>1,t1(0),t2(0

); ll tt(0);

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

else

}else

else}}

for(int i=1;i<=t1;i++) if(p1[i].opt) update(p1[i].x,-1),update(p1[i].y+1,1

);

for(int i=1;i<=t1;i++) p[l+i-1]=p1[i];

for(int i=1;i<=t2;i++) p[l+t1+i-1]=p2[i];

solve(l,l+t1-1

,x,mid);

solve(l+t1,r,mid+1

,y);

}int

main()

solve(

1,m,0,n<<1

);

for(int i=1;i<=cnt;i++) printf("

%d\n

",n-ans[i]);

return0;

}

題解 P3332 ZJOI2013 K大數查詢

link 你需要維護 n 個可重整數集,集合的編號從 1 到 n 這些集合初始都是空集,有 m 個操作 1 leq n m leq 10 5 1 leq c leq 2 發現插入,查詢 k 大,考慮線段樹套平衡樹。但是發現 n m leq 10 5 並且區間插入並不好打懶標記,比較麻煩。並且因為平衡...

洛谷 P3332 ZJOI2013 K大數查詢

題目 k大數查詢 思路 整體二分。維護兩個區間 l,r 和 l,r 分別代表二分的答案區間,和可以滿足答案的詢問區間。在 l,r 上二分m。對於1操作,如果v小於m,在 q.l,q.r 上用線段樹實現區間加一,值賦1,否則賦0。對於2操作,詢問 q.l,q.r 上的數的個數s,若v小於等於s,值賦1...

洛谷P3332 ZJOI2013 K大數查詢

description 帶區間修求區間第kkk大 資料範圍 n 5 104 n leq 5 times 10 4 n 5 104so luti on solution soluti on字首和套主席樹可以解決靜態 樹狀陣列套主席樹可以解決單點修改區間查詢 貌似在這道題,外層套乙個可以區間修改區間查詢...