题目链接:https://www.luogu.org/problemnew/show/P2048
解题思路:
建立主席树对于第i颗线段树来说,区间(l,r)表示左端点是l-r的点,右端点是i的区间情况,对此第i颗线段树由i-1颗转移过来时只需要对当前线段树进行(1,i)区间都加上a[i]的值,那么这个操作就可以做区间更新,之后就是维护线段树区间最大值和位置就OK了.
然后先把i个最大值插入优先队列,i个最大值分别为第i个线段树的可选择的区间长度大小,即(i-R+1,i-L+1)中的最大值,假设在此区间中的最大值位置在m,取出之后将区间分裂为(i-R+1,m-1)和(m+1,i-L+1),对这两个区间还是可以用线段树求出最大值和位置,然后将这两个插入队列中即可,在队列中取出前k个元素就是前k大的区间和。
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define lson l,mid
#define rson mid+1,r
using namespace std;
typedef long long ll;
const int mx = 5e5 + 10;
const int mod = 1e9+7;
int n,m,L1,R1,root[mx];
int a[mx],add[mx*30],rs[mx*30];
int siz,ls[mx*30],d;
struct node
{
int rt,l,r;
int p,c;
bool operator < (node A)const
{
return c < A.c;
}
};
struct data
{
int ps,Ma;
}s[mx*30];
pri