題意:區間修改樹上兩點間的顏色種類,區間查詢樹上兩點間的線段數。
思路:樹刨+線段樹,區間合併是第一次寫。思路為線段樹維護左端點和右端點的顏色,合併時相同就–。具體實現不太好寫。
**:
#include
using
namespace std;
#define ll long long
#define forn(i,n) for(int i=0;i#define for1(i,n) for(int i=1;i<=n;i++)
#define io ios::sync_with_stdio(false);cin.tie(0)
const
int maxn =
1e5+5;
int a[maxn]
,top[maxn]
,sz[maxn]
,son[maxn]
,deep[maxn]
,p[maxn]
,par[maxn]
,fp[maxn]
,id,now;
vector<
int>e[maxn]
;class
segment_tree
}node[maxn<<2]
;void
pushup
(int now)
void
pushdown
(int now)
}void
maketree
(int l,
int r,
int now =1)
;if(l==r)
maketree
(l,l+r>>
1,now<<1)
;maketree
((l+r>>1)
+1,r,now<<1|
1);pushup
(now);}
void
update
(int l,
int r,
int v,
int now =1)
pushdown
(now);if
(l<=ndl.r)
update
(l,r,v,now<<1)
;if(r>=ndr.l)
update
(l,r,v,now<<1|
1);pushup
(now);}
intquery
(int l,
int r,
int now =1)
else
if(l<=ndl.r) res+
=query
(l,r,now<<1)
;else
if(r>=ndr.l) res+
=query
(l,r,now<<1|
1);pushup
(now)
;return res;
}int
getcr
(int pos,
int now =1)
}tree;
void
dfs(
int u,
int pre,
int d)
}void
getpos
(int u,
int gg)
}bool
check
(int x,
int y)
intquery
(int x,
int y)
if(deep[x]
>deep[y]
)swap
(x,y)
; res+
=tree.
query
(p[x]
,p[y]);
return res;
}void
change
(int x,
int y,
int v)
if(deep[x]
>deep[y]
)swap
(x,y)
; tree.
update
(p[x]
,p[y]
,v);
}int
main()
dfs(1,
0,0)
;getpos(1
,1);
tree.
maketree(1
,n);
while
(m--
)else
}return0;
}
BZOJ 2243 樹鏈剖分 線段樹
include define n 101000 define frei freopen in.txt r stdin define freo freopen out.txt w stdout define mem a,b memset a,b,sizeof a define lson root 1 ...
BZOJ2243 樹鏈剖分 線段樹)
problem 染色 bzoj2243 題目大意 給定一顆樹,每個節點上有一種顏色。要求支援兩種操作 操作1 將a b上所有點染成一種顏色。操作2 詢問a b上的顏色段數量。解題分析 樹鏈剖分 線段樹。開乙個記錄型別,記錄某一段區間的資訊。l 表示區間最左側的顏色 r 表示區間最右側的顏色 sum ...
BZOJ 2243 染色 線段樹 樹鏈剖分
time limit 20 sec memory limit 512 mb submit 7964 solved 2987 submit status discuss 給定一棵有n個節點的無根樹和m個操作,操作有2類 1 將節點a到節點b路徑上所有點都染成顏色c 2 詢問節點a到節點b路徑上的顏色段...