有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
輸出每個詢問的結果
2 51 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 312
1【樣例說明】
第乙個操作 後位置 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
/*動態第k大,整體二分的經典題目。
思想和靜態的是差不多的,即二分出答案之後用樹狀陣列判斷,但是這個題目樹狀陣列用了兩個,就不是很懂了。
*/#include
#include
#include
#include
#define lon long long
#define n 50010
using
namespace
std;
lon n,m,c1[n],c2[n],ans[n],has[n];
struct
node;node a[n],q[n];
void add(lon *c,lon i,lon b)
lon sum(lon *c,lon i)
void
modify(lon l,lon r,lon c)
lon pre(lon i)
lon query(lon l,lon r)
void
solve(lon head,lon tail,lon l,lon r)
lon mid=l+r>>1
; lon l1=head,l2=tail;
for(lon i=head;i<=tail;i++)
else
else q[l2--]=a[i];}}
reverse(q+l2+1,q+tail+1
);
for(lon i=head;i<=tail;i++)
solve(head,l1-1
,l,mid);
solve(l1,tail,mid+1
,r);
}int
main()
solve(
1,m,1
,n);
for(lon i=1;i<=m;i++)
if(has[i])printf("
%lld\n
",ans[i]);
return0;
}
K大數查詢 BZOJ 3110
k大數查詢 問題描述 有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 輸出格...
BZOJ 3110, K大數查詢
傳送門 要求維護乙個數列,支援在某部分的每個位置填上乙個數以及查詢某部分第k大的數字。終於學習了一下樹套樹的姿勢 其實和自己想的也差不多 但是不學還是打不出 來 外層是權值線段樹,內層是區間線段樹。要注意的細節比較多。二分查詢過程中結果可能超過maxlongint,需要用unsigned int型別...
bzoj 3110 K大數查詢 樹套樹
題目傳送門 time limit 20 sec memory limit 512 mb submit 5039 solved 1751 submit status discuss 有n個位置,m個操作。操作有兩種,每次操作如果是1 a b c的形式表示在第a個位置到第b個位置,每個位置加入乙個數c ...