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