洛谷P4315 月下「毛景樹」 邊權樹剖 雙標記

2022-03-18 00:07:24 字數 3037 閱讀 1616

題目鏈結

做這道題的時候,乍一看很熟悉,之前考試時也做過類似的題。這道題樹剖+線段樹是個人都看得出來,不過覆蓋標記和加標記同時下放是這道題最坑的地方。當時考試的時候就被這東西搞慘了。

做法:樹剖維護邊權的時候等效於維護兩點之間深度較深的點的點權,這很好理解。

在修改和查詢的時候,注意到這張圖,我們假定修改f和g路徑裡的邊權。這個時候我們同一般的樹剖來跳,最後當他們在同一條鏈上時,其中有乙個必然為另乙個的祖先,但我們不能去改祖先的維護的那個點值,因為那個邊沒有在f->g的路徑上。所以利用dfs序的連續性,要將祖先的dfs序+1,這樣就改不到祖先那裡去,只能改路徑上的邊權。同時下放兩個標記的時候,覆蓋標記的優先順序是比加標記要大的,所以我們必須要先下放覆蓋標記,而一旦有了覆蓋標記,之前的所有標記全部作廢,所以我們還要把加標記賦為0。並且要注意覆蓋標記初始值為-1。

**如下:

1 #include2

using

namespace

std;

3const

int maxn=1e6+7;4

intn,x,y,v;

5struct

nodeedge[maxn*3];8

struct

node1tree[maxn*4

];12

inthead[maxn],cnt;

13void add(int x,int y,int

v)20

long

long max(long

long a,long

long

b)23

intdep[maxn],fa[maxn],top[maxn],size[maxn],son[maxn],id[maxn],rev[maxn],w[maxn];

24void dfs1(int x,int

f)39}40

}41inttime;

42void dfs2(int x,int

topf)53}

54void build(int now,int l,int

r)60

int mid=(l+r)>>1

;61 build(now<<1

,l,mid);

62 build(now<<1|1,mid+1

,r);

63 tree[now].mx=max(tree[now<<1].mx,tree[now<<1|1

].mx);64}

65void pushdown(int

now)

74if

(tree[now].lazy2)81}

82void update1(int now,int l,int r,int

v)88

pushdown(now);

89int mid=(tree[now].l+tree[now].r)>>1;90

if(l<=mid) update1(now<<1

,l,r,v);

91if(r>mid) update1(now<<1|1

,l,r,v);

92 tree[now].mx=max(tree[now<<1].mx,tree[now<<1|1

].mx); 93}

94void update2(int now,int l,int r,int

v)101

pushdown(now);

102int mid=(tree[now].l+tree[now].r)>>1

;103

if(l<=mid) update2(now<<1

,l,r,v);

104if(r>mid) update2(now<<1|1

,l,r,v);

105 tree[now].mx=max(tree[now<<1].mx,tree[now<<1|1

].mx);

106}

107long

long query(int now,int l,int

r)116

void link1(int x,int y,int

v)122

if(dep[x]

123 update1(1,id[y]+1

,id[x],v);

124}

125void link2(int x,int y,int

v)131

if(dep[x]

132 update2(1,id[y]+1

,id[x],v);

133}

134long

long linkquery(int x,int

y)142

if(dep[x]

143 ans=max(ans,query(1,id[y]+1

,id[x]));

144return

ans;

145}

146char opt[5

];147

intu,j,a,k;

148int

main()

154 dfs1(1,0

);155 dfs2(1,1

);156 build(1,1

,n);

157while(1

)165

if(opt[0]=='

c'&&opt[1]=='o'

)169

if(opt[0]=='a'

)173

if(opt[0]=='m'

)177

if(opt[0]=='

s') break

;178

}179

return0;

180 }

view code

洛谷P4315 月下「毛景樹」

毛毛蟲經過及時的變形,最終逃過的一劫,離開了菜媽的菜園。毛毛蟲經過千山萬水,歷盡千辛萬苦,最後來到了小小的紹興一中的校園裡。爬啊爬 爬啊爬毛毛蟲爬到了一顆小小的 毛景樹 下面,發現樹上長著他最愛吃的毛毛果 毛景樹 上有n個節點和n 1條樹枝,但節點上是沒有毛毛果的,毛毛果都是長在樹枝上的。但是這棵 ...

洛谷 P4315 月下「毛景樹」

題目 又是一道維護邊權的題 對於每乙個節點,我們把他的點權設為他跟他父親之間的邊權,這樣就輕鬆地把邊權轉化為了點權 但是,這題的重點就在 同時維護區間加和區間修改 對於乙個區間 k kk,我們設 max v k maxv k maxv k 為區間最大值,add k c k add k c k add...

洛谷 P4315 月下「毛景樹」(邊樹剖)

題目不算難,但是 量需要控制主要說一下線段樹上的操作,因為有兩個相關的區間操作標記,應該先覆蓋後增加,因為覆蓋操作會影響增加操作 const int n 1e5 5 int n,m int i,j,k int a n struct node t n 2 vectorg n int sz n fa n...