洛谷 P2048 主席樹 區間修改

2021-08-29 14:15:05 字數 1523 閱讀 5516

解題思路:

建立主席樹對於第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#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

};struct data

s[mx*30];

priority_queue st;

void build(int& rt,int l,int r)

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

build(ls[rt],lson);

build(rs[rt],rson);

}data up(data a,data b)

void update(int x,int &y,int l,int r,int l,int r)

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

if(r<=mid) update(ls[x],ls[y],lson,l,r);

else if(l>mid) update(rs[x],rs[y],rson,l,r);

else

s[y] = up(s[ls[y]],s[rs[y]]);

s[y].ma += add[y];

}data query(int rt,int l,int r,int l,int r)

; if(l<=mid) ans = up(ans,query(ls[rt],lson,l,r));

if(r>mid) ans = up(ans,query(rs[rt],rson,l,r));

return data;

}int main()

); }

}ll ans = 0;

data ret;

while(m--));

}if(now.r-now.p>0));} }

printf("%lld\n",ans);

return 0;

}

洛谷P2048 超級鋼琴 堆 主席樹

乙個長度為n n的序列,求m m個長度在 l,r l r 之間的子串行,使得這些子串行的元素之和最大。顯然暴力是很難搞的,考慮先用字首和。那麼我們要求的就是 i 1mm ax s um k su m x 1 x l 1 k x r 1 i 1 m max sum k s um x 1 x l 1 k...

靜態主席樹(區間第k小) 洛谷P3834

時間限制1.00s 1.20s 記憶體限制125.00mb 250.00mb 這是個非常經典的主席樹入門題 靜態區間第k小 資料已經過加強,請使用主席樹。同時請注意常數優化 如題,給定n個整數構成的序列,將對於指定的閉區間查詢其區間內的第k小值。第一行包含兩個正整數n m,分別表示序列的長度和查詢的...

線段樹 單點修改 區間查詢 洛谷P4588

想了半天 這個和線段樹什麼關係!最後發現我就是豬豬 害就是個板子題 把每乙個葉子節點的值賦值為1 如果第m個是1 n 就把m這個點的值變為n 如果是2 n 就把n點的值變為1 include include include include include include include includ...