有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 51 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3
輸出樣例#1:
121
【樣例說明】
第乙個操作 後位置 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字首和套主席樹可以解決靜態 樹狀陣列套主席樹可以解決單點修改區間查詢 貌似在這道題,外層套乙個可以區間修改區間查詢...