HYSBZ3110 K大數查詢

2021-08-09 02:28:44 字數 1801 閱讀 7722

time limit: 20 sec  

memory limit: 512 mb

submit: 9350  

solved: 2761 [

submit][

status][

discuss]

有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

解題思路:線段樹套線段樹,外面一棵是權值線段樹,裡面一棵是區間線段樹

#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;

#define ll long long

const int inf = 0x3f3f3f3f;

const int maxn = 50009;

struct node

a[maxn];

long long x[maxn];

int n, m, cnt, tot;

int s[200005], l[20000005], r[20000005];

long long sum[20000005], lazy[20000005];

void push(int k, int l, int r)

void update(int &k, int l, int r, int ll, int rr)

if(lazy[k]) push(k, l, r);

int mid = (l + r) >> 1;

if (ll <= mid) update(l[k], l, mid, ll, rr);

if (rr > mid) update(r[k], mid + 1, r, ll, rr);

sum[k] = sum[l[k]] + sum[r[k]];

}void insert(int ll, int rr, int p)

update(s[k], 1, n, ll, rr);

}ll query(int k, int l, int r, int ll, int rr)

int solve(int ll, int rr, ll p)

return l;

}int main()

else printf("%lld\n", x[solve(a[i].l, a[i].r, a[i].z)]);

} return 0;

}

BZOJ 3110, K大數查詢

傳送門 要求維護乙個數列,支援在某部分的每個位置填上乙個數以及查詢某部分第k大的數字。終於學習了一下樹套樹的姿勢 其實和自己想的也差不多 但是不學還是打不出 來 外層是權值線段樹,內層是區間線段樹。要注意的細節比較多。二分查詢過程中結果可能超過maxlongint,需要用unsigned int型別...

K大數查詢(bzoj 3110)

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

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 輸出格...