BZOJ 2157 旅遊 樹剖 線段樹

2021-09-13 15:42:06 字數 3768 閱讀 6807

題目傳送門

題目分析:

似乎是個裸題。。

把邊權放到深度大的那個點上,查詢的時候去掉lca就好了。

(然而我雖然知道這一點打的時候仍然把lca加進去了。。 )

然後就是瘋狂複製貼上再ctrlf替換。。

然而還是wa。。寫的時候c操作改點的時候沒有用dfs序直接把點編號帶了進去。

後來又發現連邊的時候連了兩條u[i]->v[i]。。。自閉

code:

#include

#include

#include

#include

#define ll long long

#define maxn 20005

using

namespace std;

char cb[

1<<15]

,*cs,

*ct;

#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)

inline

void

read

(int

&a)const

int inf =

1<<30;

int n,m,a[maxn]

,seq[maxn]

;int dfn[maxn]

,tim,fa[maxn]

,son[maxn]

,siz[maxn]

,top[maxn]

,dep[maxn]

;int fir[maxn]

,nxt[maxn<<1]

,to[maxn<<1]

,w[maxn<<1]

,tot;

inline

void

line

(int x,

int y,

int z)

void

dfs1

(int u)

}void

dfs2

(int u,

int tp)

struct node

inline

void

reverse()

}t[maxn<<2]

;void

pushdown

(int i)

}void

upd(

int i)

void

build

(int i,

int l,

int r)

int mid=

(l+r)

>>1;

build

(i<<

1,l,mid)

;build

(i<<1|

1,mid+

1,r)

;upd

(i);

}voidc(

int i,

int l,

int r,

int x,

int d)

pushdown

(i);

int mid=

(l+r)

>>1;

if(x<=mid)

c(i<<

1,l,mid,x,d)

;else

c(i<<1|

1,mid+

1,r,x,d)

;upd

(i);

}void

inverse

(int i,

int l,

int r,

int x,

int y)

pushdown

(i);

int mid=

(l+r)

>>1;

if(x<=mid)

inverse

(i<<

1,l,mid,x,y);if

(y>mid)

inverse

(i<<1|

1,mid+

1,r,x,y)

;upd

(i);

}voidn(

int u,

int v)

if(u==v)

return;if

(dep[u]

)swap

(u,v)

;inverse(1

,1,n,dfn[v]+1

,dfn[u]);

}int

querysum

(int i,

int l,

int r,

int x,

int y)

intquerymax

(int i,

int l,

int r,

int x,

int y)

intquerymin

(int i,

int l,

int r,

int x,

int y)

intsum

(int u,

int v)

if(u==v)

return ret;

if(dep[u]

)swap

(u,v)

;return ret+

querysum(1

,1,n,dfn[v]+1

,dfn[u]);

}int

max(

int u,

int v)

if(u==v)

return ret;

if(dep[u]

)swap

(u,v)

;return ret=

max(ret,

querymax(1

,1,n,dfn[v]+1

,dfn[u]))

;}intmin

(int u,

int v)

if(u==v)

return ret;

if(dep[u]

)swap

(u,v)

;return ret=

min(ret,

querymin(1

,1,n,dfn[v]+1

,dfn[u]))

;}int u[maxn]

,v[maxn]

,p[maxn]

;int

main()

dfs1(1

),dfs2(1

,1);

for(

int i=

1;i) p[i]

=dep[u[i]

]>dep[v[i]

]?u[i]

:v[i]

;build(1

,1,n);

read

(m);

while

(m--

) x++

,y++;if

(op==

'n')

n(x,y);if

(op==

's')

printf

("%d\n"

,sum

(x,y));

if(op==

'm')

printf

("%d\n"

,op2==

'a'?

max(x,y)

:min

(x,y));

}}

BZOJ2157旅遊 樹鏈剖分 線段樹

ray 樂忠於旅遊,這次他來到了t 城。t 城是乙個水上城市,一共有 n 個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,t 城的任意兩個景點之間有且只有一條路徑。換句話說,t 城中只有n 1 座橋。ray 發現,有些橋上可以看到美麗的景色,讓人心情愉悅,但有些橋狹窄泥...

bzoj2157 旅遊 樹鏈剖分 線段樹

題目描述 ray 樂忠於旅遊,這次他來到了t 城。t 城是乙個水上城市,一共有 n 個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,t 城的任意兩個景點之間有且只有一條路徑。換句話說,t 城中只有n 1 座橋。ray 發現,有些橋上可以看到美麗的景色,讓人心情愉悅,但有...

BZOJ2157 旅遊 樹鏈剖分 線段樹

在對樹中資料進行改動的時候需要很多pushdown 具體操作見 不然會wa,大概原因和線段樹區間修改需要很多pushup是一樣的。這個輕重鏈的方法特別好用,雖然第一次寫樹鏈剖分但是容易理解又有優秀複雜度的結構讓人情不自禁orz。後來發現很久以前學lca的時候就學了樹鏈剖分只不過忘了,mdzz 因為忘...