BZOJ2157 旅遊 樹鏈剖分 線段樹

2022-05-26 09:30:12 字數 3233 閱讀 7341

在對樹中資料進行改動的時候需要很多pushdown(具體操作見**),不然會wa,大概原因和線段樹區間修改需要很多pushup是一樣的。

這個輕重鏈的方法特別好用,雖然第一次寫樹鏈剖分但是容易理解又有優秀複雜度的結構讓人情不自禁orz。

(後來發現很久以前學lca的時候就學了樹鏈剖分只不過忘了,mdzz)

因為忘了去掉測試**的freopen,re了4次(雖然有三次就算不re也wa),發現一行一行檢查對於資料結構的除錯很有用(雖然一直找不出來re原因但是我起碼避免了很多wa呀)。

**

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;

7const

int maxn=20100;8

const

long

long modn=1000000007;9

const

int minf=1

<<30;10

int n,m;char ch[5]={};

11struct

node[maxn*2

];14

int head[maxn]={},tot=0;15

struct

seg19 }t[maxn*4

];20

int dep[maxn]={},crs[maxn]={},pos[maxn]={},road[maxn]={};

21int kid[maxn]={},fa[maxn]={},top[maxn]={};

22void init(int x,int y,int

v)26

int dfs1(int x,int

pa)36

return

tsn;37}

38void dfs2(int x,int

pa)49}50

void pushup(int

x)56

void pushdown(int

x)67

return;68

}69if(t[x].rev)78}

79}80void build(int x,int l,int

r)86

int mid=(l+r)/2

;87 build(x*2

,l,mid);

88 build(x*2+1,mid+1

,r);

89pushup(x);90}

91void cov(int x,int l,int r,int

w)96

pushdown(x);

97int mid=(t[x].l+t[x].r)/2;98

if(l<=mid)cov(x*2

,l,r,w);

99 pushdown(x*2

);100

if(r>mid) cov(x*2+1

,l,r,w);

101 pushdown(x*2+1

);102

pushup(x);

103}

104void revs(int x,int l,int

r)pushdown(x);

110int mid=(t[x].l+t[x].r)/2

;111

if(l<=mid) revs(x*2

,l,r);

112 pushdown(x*2

);113

if(r>mid) revs(x*2+1

,l,r);

114 pushdown(x*2+1

);115

pushup(x);

116}

117int mi(int x,int l,int

r)122

int mid=(t[x].l+t[x].r)/2,minn=minf;

123if(l<=mid) minn=min(minn,mi(x*2

,l,r));

124if(r>mid) minn=min(minn,mi(x*2+1

,l,r));

125return

minn;

126}

127int mx(int x,int l,int

r)132

int mid=(t[x].l+t[x].r)/2,mxn=-minf;

133if(l<=mid) mxn=max(mxn,mx(x*2

,l,r));

134if(r>mid) mxn=max(mxn,mx(x*2+1

,l,r));

135return

mxn;

136}

137int su(int x,int l,int

r)142

int mid=(t[x].l+t[x].r)/2,sumn=0

;143

if(l<=mid) sumn+=su(x*2

,l,r);

144if(r>mid) sumn+=su(x*2+1

,l,r);

145return

sumn;

146}

147void mrev(int x,int

y)154

if(dep[x]>dep[y])swap(x,y);

155if(x!=y) revs(1,pos[x]+1

,pos[y]);

156}

157void doit(int x,int y,int

k)166

if(dep[x]>dep[y])swap(x,y);

167if(x!=y)

172if(k==0) printf("

%d\n

",sumn);

173else

if(k==1) printf("

%d\n

",mxn);

174else printf("

%d\n

",minn);

175}

176int

main()tot=0;dfs1(1,1);dfs2(1,1

);185 build(1,1

,n);

186 scanf("

%d",&m);

187for(int i=1;i<=m;i++)

195return0;

196 }

view code

BZOJ2157旅遊 樹鏈剖分 線段樹

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

bzoj2157 旅遊 樹鏈剖分 線段樹

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

BZOJ 2157 旅遊 樹鏈剖分

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