我之前考試是遇到過這題,但是資料範圍k<=20,狀壓就能過。
結果原題範圍k<=100000……
果斷線段樹合併。
比如兩個相同大小的線段樹,將b樹各個區間上的值合併到a樹上,從樹根開始合併,然後遞迴合併左右兒子,有三種情況:
(假設現在a樹遍歷到x點,b樹遍歷到y點)
1.x,y至少其一未被修改過(語文不好勿噴),則將x變為遍歷過的那個。
2.x,y位於葉節點(l==r),則sum[x]+=sum[y]。
3.一般情況,遞迴處理左右兒子,最後更新當前點。
本題中合併如下:
void merge(int &a,int b,int l,intr) //1
if(l==r)//
注意維護
//2int mid = (l+r)>>1
; merge(ls[a],ls[b],l,mid);
//遞迴左子樹
merge(rs[a],rs[b],mid+1,r);//
遞迴右子樹
update(a);
//3}
juruo**奉上:
#include#includeusing
namespace
std;
#define n 100105inline
intrd()
while(ch>='
0'&&ch<='9')
return f*c;
}int
n,m,hed[n],cnt;
struct
ege[
2*n];
void ae(int f,int
t)int
dep[n],fa[n],son[n],tp[n],siz[n];
void dfs1(intu)}
void dfs2(int u,int
topn)
}int get_lca(int a,int
b)
return dep[a]a:b;
}int rt[n],sum[70*n],sn[70*n],ls[70*n],rs[70*n],tot;
void update(int
u)void insert(int l,int r,int &u,int qx,int
d)
int mid = (l+r)>>1
;
if(qx<=mid)insert(l,mid,ls[u],qx,d);
else insert(mid+1
,r,rs[u],qx,d);
update(u);
}void merge(int &a,int b,int l,int
r)
if(l==r)
int mid = (l+r)>>1
; merge(ls[a],ls[b],l,mid);
merge(rs[a],rs[b],mid+1
,r);
update(a);
}int
ans[n];
void dfs(int
u) ans[u]=sn[rt[u]];
}struct
ndnd[n];
bool
cmp(nd a,nd b)
intto[n];
intmain()
dfs1(
1),dfs2(1,1
);
for(int f,t,z,i=1;i<=m;i++)
sort(nd+1,nd+1+m,cmp);
int las=-1,k=0
;
for(int f,t,z,lca,i=1;i<=m;i++)
nd[i].z=k;
f = nd[i].f,t = nd[i].t,z =nd[i].z;
lca =get_lca(f,t);
insert(
1,m,rt[f],z,1
); insert(
1,m,rt[t],z,1
); insert(
1,m,rt[lca],z,-1
);
if(lca!=1)insert(1,m,rt[fa[lca]],z,-1
); }
dfs(1);
for(int i=1;i<=n;i++)
return0;
}
在這裡提一下空間問題:
每進行一次插入,會新增log級的點,因此juruo認為開nlogn級陣列即可。
Vani有約會 雨天的尾巴
題意 有一棵n個點的樹,m次操作,每次操作給路徑 u,v 上每個點發乙個型別為w的物品。在所有操作後請你求出每個點個數最多的物品型別。n,m,w leq 10 題解 樹鏈剖分基本就是把序列問題上樹,於是考慮序列怎麼做,直接把區間加改成差分再維護一棵權值線段樹即可。複雜度 o n log 注意那個w不...
P4556 Vani有約會 雨天的尾巴
目錄每個節點維護一課線段樹 當然是動態開點 線段樹的作用是統計這個節點有多少種糧食型號,以及最多的糧食型號 然後樹上差分,u和v點 1,lca u,v 和f lca u,v 1 不顯然就畫圖嘍 並不用轉化為dfs序 只需要dfs一邊,自底向上合併就好 刪除節點不必建樹 因為在遞迴到他的時候一定是存在...
Vani有約會 雨天的尾巴 線段樹合併
樹上差分 線段樹合併.在每個節點上維護一棵權值線段樹.然後如果需要修改 x,y 兩點,則在 x 處和 y 處分別加上 1 的權值.然後在 lca x,y 以及 fa lca x,y 處減掉 1 最後面 dfs 從下往上更新.由於每一次維護只維護四個點的值,且每次在每一棵樹上也只會修改一條鏈的值.每次...