K大數查詢(bzoj 3110)

2022-05-14 06:04:34 字數 1590 閱讀 7729

有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 ...