數鏈剖分(樹的統計Count )

2022-03-05 16:53:05 字數 2998 閱讀 6500

具體思路:單點更新,區間查詢,查詢的時候有兩種操作,查詢區間最大值和區間和。

注意點:在查詢的時候,我們應該直接將這個點進行查詢,而不是荊這個點在樹上的編號進行查詢,只有在進入線段樹的時候我們才用樹上的編號,update的時候也就直接用樹上的編號就可以了,注意這個題有點權值會有負值的情況。

ac**:

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8

using

namespace

std;

9 # define ll long

long

10 # define inf 0x3f3f3f3f

11 # define lson l,m,rt<<1

12 # define rson m+1,r,rt<<1|1

13const

int maxn = 60000+100;14

inthead[maxn],edgnum,sto[maxn],depth[maxn],size[maxn],father[maxn];

15int

son[maxn],ord[maxn],dfsnum,cost[maxn],top[maxn];

16int tree1[maxn<<2],tree2[maxn<<2

];17

intmaxx;

18struct

node

19 edge[maxn];

24void addedge(int fr,int

to)25

31void dfs1(int fr,int rt,int

dep)

3248}49

}50void dfs2(int fr,int

rt)51

59for(int i=head[fr]; i!=-1; i=edge[i].nex)

6066}67

}68void up1(int

rt)69

72void up2(int

rt)73

76void buildtree(int l,int r,int

rt)77

84int m=(l+r)>>1;85

buildtree(lson);

86buildtree(rson);

87up1(rt);

88up2(rt);89}

90void query1(int l,int r,int rt,int l,int

r)91

97int m=(l+r)>>1;98

if(l<=m)

99query1(lson,l,r);

100if(r>m)

101query1(rson,l,r);

102up1(rt);

103}

104void query1(int n,int x,int

y)105

115 query1(1,n,1

,ord[tx],ord[x]);

116 x=father[tx],tx=top[x];

117}

118if(depth[x]119122 query1(1,n,1

,ord[y],ord[x]);

123}

124int query2(int l,int r,int rt,int l,int

r)125

130int ans=0

;131

int m=(l+r)>>1

;132

if(l<=m)

133 ans+=query2(lson,l,r);

134if(r>m)

135 ans+=query2(rson,l,r);

136up2(rt);

137return

ans;

138}

139int query2(int n,int x,int

y)140

150 ans+=query2(1,n,1

,ord[tx],ord[x]);

151 x=father[tx],tx=top[x];

152}

153if(depth[x]154157

return ans+query2(1,n,1

,ord[y],ord[x]);

158}

159void update(int l,int r,int rt,int pos,int

p)160

167int m=(l+r)>>1

;168

if(pos<=m)

169update(lson,pos,p);

170if(pos>m)

171update(rson,pos,p);

172up1(rt);

173up2(rt);

174}

175int

main()

176183

intt1,t2;

184for(int i=1; i)

185190

for(int i=1; i<=n; i++)

191194 dfs1(1,-1,1

);195 dfs2(1,1

);196 buildtree(1,n,1

);197

intq;

198char str[100

];199 scanf("

%d",&q);

200while(q--)

201209

else

if(str[0]=='

q'&&str[1]=='s'

)210

215else

if(str[0]=='c'

)216

220}

221return0;

222 }

BZOJ 1036 樹的統計 Count 樹鏈剖分

題目大意 一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 ...

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...

ZJOI2008 樹的統計(樹鏈剖分)

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 從點...