塊狀樹裸題
塊狀樹:
首先對樹進行分塊,分出的每一塊都是乙個連通塊
通常的分塊的方式如下:
1、父親所在塊不滿,分到父親所在塊中
2、父親所在塊滿,自己單獨開乙個塊
(貌似有更為優越的分塊方式?
注意這是不嚴格的分塊,即每個塊的大小不一定都是設定的閾值blo
對於這道題,首先修改和新增直接塊內暴力就可以了
對於詢問,首先我們對每個塊排序,塊不完全在詢問子樹內的單點詢問,塊完全在詢問子樹內的塊內二分
分塊真是騙分利器,但是塊狀樹最大的缺點是容易被菊花樹卡住
(貌似修改和新增可以去掉乙個log,但是我太弱了,並不想寫)
#include#includegty的妹子樹#include
#include
#include
#include
using
namespace
std;
const
int oo=0x7fffffff
;const
int maxn=200010
;int
n,m,u,v,f,ans,tot,blo;
intpos[maxn],fa[maxn],w[maxn];
int a[10010][510],cnt[10010
];struct
graph
}g,t;
void read(int &num)
bool cmp(const
int &i,const
int &j)
void check_block(int
u)else a[k][++cnt[k]]=w[u],pos[u]=k;
for(int i=g.h[u];i;i=g.next[i])
return;}
int get_pos(int
u)returnl;}
void get_block(int
u)void get_ask(int
u)return;}
void get_insert(int u,int
k)void get_modify(int
u) }
w[u]=v;
sort(a[k]+1,a[k]+cnt[k]+1
,cmp);}
intmain()
for(int i=1;i<=n;++i)read(w[i]);
blo=(int
)(sqrt(n));
fa[1]=1;pos[1]=1;tot=1
; check_block(1);
for(int i=1;i<=tot;++i)sort(a[i]+1,a[i]+cnt[i]+1
,cmp);
//for(int i=1;i<=n;++i)cout/
cout
while(m--)
else
if(f==2
)else
get_insert(n,pos[u]);
}else
get_modify(u);
}return0;
}
bzoj3720 Gty的妹子樹
我們可以樹上分塊,詳見我部落格中雜文下的根號演算法題庫 然後每個塊維護降序,對於整一塊在子樹內的就可以二分,其餘部分暴力。include include include include define fo i,a,b for i a i b i using namespace std const i...
BZOJ3720 Gty的妹子樹
如果沒有插入操作,那麼直接對dfs序建立線段樹套平衡樹即可,有插入操作的話,將外層的線段樹換成重量平衡樹即可。一開始寫替罪羊樹套權值線段樹無限mle 所以只好寫替罪羊樹套treap include include includeusing namespace std typedef unsigned...
BZOJ3720 Gty的妹子樹
題目 題解 傳說中的塊狀樹。和鏈剖思想差不多,能塞到父親塊裡的就塞,否則自己新開一塊。只是比較糾結樹分塊究竟用什麼?如果是樹上莫隊的話好像不能這麼分?被菊花卡死?然後我們就每個塊暴力維護資訊。剛開始以為set就行了,到了寫查詢的時候發現尼瑪set是不能維護名次的t t 還是老老實實寫線性表吧。塊開s...