最近學了樹鏈剖分,又可以做好多好多難題水題真是噁心開心!!!
luogu上的主席樹標籤迷惑了我好久,,,結果好像只用到了主席樹的思想,主席樹的操作根本沒有....
沒有宗教的限制,這道題就是樹剖的sum和max操作。但是,也很容易想到,對於每乙個宗教就建一顆樹,於是就可以每次都能夠進行查詢每個宗教的東西了。很明顯,空間**呀,動態開點就來咯!這裡用到乙個主席樹思想就是每乙個宗教建一顆樹,可能也算是勉強有主席樹元素吧。
注意一些小操作-》如果某個點改宗教,原宗教線段樹里直接改成0,然後記錄下w,返回到新的宗教線段樹里就可以了
以及!!!修改原來的宗教陣列(也只有菜雞如我才會搞忘),恩,陣列開大一點。
認真寫,沒有寫出小bug這道題還是挺簡單的,樹剖板子題一道,寫出bug,呵呵,慢慢調吧。
#include#include#define midd ((l+r)>>1)這裡的擴棧操作是因為nkoj會棧記憶體不夠。。。using namespace std;
const int maxn=100005;
int n,q;
int oldw[maxn],oldc[maxn];
int la[maxn<<1],nt[maxn<<1],en[maxn<<1],owo;
inline void addedge(int a,int b)
//int size[maxn],dep[maxn],zerz[maxn],top[maxn],newid[maxn],fa[maxn],oldid[maxn],idcnt;
void fzb(int x,int ba) }}
void lzb(int x,int ace)}//
int tot,rt[maxn];
struct node
z[maxn<<5];
inline void putup(int p)
void ins(int &p,int oid,int ww,int l,int r)
if(oid<=midd) ins(z[p].ls,oid,ww,l,midd);
else ins(z[p].rs,oid,ww,midd+1,r);
putup(p);
}void del(int &p,int oid,int &ww,int l,int r)
if(oid<=midd) del(z[p].ls,oid,ww,l,midd);
else del(z[p].rs,oid,ww,midd+1,r);
putup(p);
}int qsum(int &p,int x,int y,int l,int r)
int qmax(int &p,int x,int y,int l,int r)
//int querysum(int cc,int x,int y)
int querymax(int cc,int x,int y)
//void main_main()
for(int i=1;i<=n-1;i++)
fzb(1,0); lzb(1,1);
for(int i=1;i<=n;i++)
ins(rt[oldc[i]],newid[i],oldw[i],1,n);
char ss[3];
while(q--)
else if(ss[1]=='c')
else if(ss[1]=='w')
else if(ss[1]=='m')
}}const int main_stack=16;
char my_stack[128<<20];
int main()
少有的一道乙個小時就搞出來了的資料結構題。。。
bzoj3531 Sdoi2014 旅行 樹剖
對每種宗教都建立線段樹,建立過程類似主席樹,在需要修改時動態建立線段樹 初始時不建立 所以空間複雜度是o nlog n ps 為什麼第二份會t啊 include include include define m 6000005 define inf 1 30 using namespace std ...
BZOJ3531 旅行 樹鏈剖分
題目大意 給定一棵樹,點染色,修改點權,鏈上詢問點權和或者最大值 資料規模10 5 主要思想是對每種顏色開一顆線段樹,動態分配記憶體,染色時刪除原來的點,加入到新線段樹中即可。需要注意的是不僅插入要更新資訊,刪除也要更新資訊。自己的 include include define safe x,a x...
BZOJ 3531 旅行 樹鏈剖分 動態開點
題目鏈結 無優化版本 170行 首先樹剖可以維護樹上的鏈sum max 可以對每個宗教建一棵線段樹,那這題就很好做了 不過10 5需要動態開點 不明白為什麼nlogn不需要 就可以 不是每個insert加log個節點?操作修改完更改原數列!盲人。include include include def...