bzoj3065帶插入區間K小值

2021-07-11 17:45:46 字數 1446 閱讀 2130

這題其實好像很難,但是聽werkeytom_ftd說可以用塊鏈水,於是就很開心地去打了個塊狀鍊錶套主席樹,插入操作就直接插到乙個塊中,注意如果塊的大小2*block就將塊分開,注意每乙個修改或插入都要修改後繼的狀態,貼**:

#include

#include

#include

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define fd(i,a,b) for(int i=a;i>=b;i--)

using namespace std;

const int n = 35010;

const int m = 610;

const int lim = 70000;

int root[m][m],s[m],a[m][m],next[m],m;

struct pointtree[m*m

*2*18];

int tot;

int n,q,block,lastans,dep,u1,v1,u2,v2;

int rt[m];

int tt[m*m

*2*18],head,tail;

void find(int

x,int &u1,int &v1)

ss+=s[i];

}}void prepare()

int getp()

void putp(int

x)void clear(int

x)void inse(int l,int r,int qf,int &now,int

x,int v)

else

}int getans(int l,int r,int k)

else fo(i,v1,v2)if (l<=a[u1][i]&&a[u1][i]<=mid)ss++;

if (ss>=k)

else

}int main()

int u=(n-1)/block;

fo(i,1,u)

int tim=0;

s[u+1]=n-u*block;

m=u+1;

scanf("%d",&q);

fo(haha,1,q)

if (ch=='m')

}if (ch=='i')

}else

}else

a[m][v1]=val;

inse(0,lim,root[m][v1-1],root[m][v1],val,1);

fo(i,v1+1,block)

s[u1]=block;

next[m]=next[u1];

next[u1]=m;}}

}}

return

0;}

好吧,vfleaking說正解是這樣的:

BZOJ3065 帶插入區間K小值

因為需要支援插入,所以外層需要乙個平衡樹,替罪羊樹比較好寫 內層需要帶修改,求k小值,可以使用權值線段樹維護平衡樹每個節點子樹內的所有權值,求k小值時二分查詢 所以是平衡樹套權值線段樹 include include include include include using namespace s...

BZOJ 3065 帶插入區間K小值

思路 做法比較多,我寫的是權值線段樹套平衡樹,平衡樹內維護該權值區間內各元素位置,每次查詢從線段樹根結點開始左右走就可以了。現在問題是如何解決帶插入的情況下快速比較兩個位置標號的前後關係,我們可以用替罪羊樹維護,我們給每個位置標號定個rank區間,例如根定為 0,1e18 定其rank值為中點5 1...

BZOJ3065 替罪羊樹套線段樹

以前看到這題都瑟瑟發抖,終於過了心情舒暢。按下標為關鍵字建替罪羊樹,每個結點開乙個權值線段樹,維護的這個結點代表的子樹的資訊。這題還得垃圾 自己yy的,不知對不對.include include using namespace std define m l r 1 define l x t x s ...