description
对于一个整数序列,查询区间第k大数可以在O(logN)的时间内轻松完成。现在我们对这个问题进行推广。
考虑带重复数的集合(multiset)。定义在该类集合上的并操作“+”为两个集合的所有数不剔除重复得到的结果。比如,若A={1,2,2,3},B={2,3,4,4},则C={1,2,2,2,3,3,4,4}。
对于一个给定序列A[1…N],定义A[x…y]为包含y-x+1个元素的集合{A[x],A[x+1],…,A[y]}。现在,给定整数序列A,你需要回答很多询问,其中第i个询问要求集合A[x[i,1]…y[i,1]]+A[x[i,2]…y[i,2]]+…+A[x[i,ki]…y[i,ki]]中第pi小的元素。
analysis
-
一年的时间使我变成了主席树傻子
-
一个区间当然可以直接主席树做,五个区间其实也可以
-
aaa的值并不是很大,不需要离散化
-
对于当前查询,可以求出五个区间左儿子区间里面数的个数之和,然后和查询值比较
-
然后向左或右儿子继续二分,把五个区间也向左或向右挪就好
-
主席树是真的虚,一定一定要多做点题,巩固老知识,才能更好学习新知识
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 200005
#define MAX 1000005
#define ll long long
#define fo(i,a,b) for (ll i=a;i<=b;++i)
#define fd(i,a,b) for (ll i=a;i>=b;--i)
using namespace std;
ll lson[MAX*20],rson[MAX*20],sum[MAX*20];
ll a[MAXN],root[MAXN];
ll n,m,mx,k,p,tot;
ll L[10],R[10];
inline ll read()
{
ll x=0,f=1;char ch=getchar

最低0.47元/天 解锁文章
3454

被折叠的 条评论
为什么被折叠?



