poj3237--Tree 树链剖分

题意:三种操作 ①修改第i条边的权值为val,②把u到v路径上的所有边的权值 去相反数③求u 到v路径上最大的边权

线段树的区间更新还是不熟练,,一直搞不对调试了好久还是没对,最后还是看的kuangbin的代码。

 

  1 #include <cstdio>

  2 #include <cstdlib>

  3 #include <iostream>

  4 #include <algorithm>

  5 #include <cstring>

  6 using namespace std;

  7 typedef unsigned long long ull;

  8 typedef long long ll;

  9 const int inf = 0x3f3f3f3f;

 10 const double eps = 1e-8;

 11 const int maxn = 1e5+10;

 12 struct

 13 {

 14     int to,next;

 15 }e[maxn<<1];

 16 int head[maxn],edge;

 17 void add(int x,int y)

 18 {

 19     e[edge].to = y;

 20     e[edge].next = head[x];

 21     head[x] = edge++;

 22 }

 23 int son[maxn],fa[maxn],siz[maxn],dep[maxn];

 24 void dfs(int root)

 25 {

 26     siz[root] = 1;

 27     son[root] = 0;

 28     for (int i = head[root]; i > 0; i = e[i].next)

 29     {

 30         if (fa[root] != e[i].to)

 31         {

 32             dep[e[i].to] = dep[root] + 1;

 33             fa[e[i].to] = root;

 34             dfs(e[i].to);

 35             if (siz[e[i].to] > siz[son[root]])

 36                 son[root] = e[i].to;

 37             siz[root] += siz[e[i].to];

 38         }

 39     }

 40 }

 41 int tot,top[maxn],li[maxn<<2],pos[maxn];

 42 void build(int root,int father)

 43 {

 44     top[root] = father;

 45     pos[root] = tot;

 46     li[tot++] = root;

 47     if (son[root] > 0)

 48         build(son[root],top[root]);

 49     for (int i = head[root]; i > 0; i = e[i].next)

 50         if (fa[root] != e[i].to && son[root] != e[i].to)

 51             build(e[i].to,e[i].to);

 52 }

 53 

 54 int minv[maxn<<2],maxv[maxn<<2], tt[maxn],lazy[maxn<<2];

 55 void build_Segtree(int l,int r,int o)

 56 {

 57     lazy[o] = 0;

 58     if (l == r)

 59     {

 60         minv[o] = tt[li[l]];

 61         maxv[o] =tt[li[l]];

 62         return;

 63     }

 64     int mid = (l + r) >> 1;

 65     build_Segtree(l,mid,o<<1);

 66     build_Segtree(mid+1,r,o<<1|1);

 67     minv[o] = min(minv[o<<1],minv[o<<1|1]);

 68     maxv[o] = max(maxv[o<<1],maxv[o<<1|1]);

 69 }

 70 char op[10];

 71 int val;

 72 inline void push_down(int l,int r,int o)

 73 {

 74     if (lazy[o]&&l!=r)

 75     {

 76         maxv[o<<1] = -maxv[o<<1];

 77         minv[o<<1] = -minv[o<<1];

 78         maxv[o<<1|1] = -maxv[o<<1|1];

 79         minv[o<<1|1] = -minv[o<<1|1];

 80         swap(maxv[o<<1],minv[o<<1]);

 81         swap(maxv[o<<1|1],minv[o<<1|1]);

 82         lazy[o<<1] ^= 1;

 83         lazy[o<<1|1] ^= 1;

 84         lazy[o] = 0;

 85     }

 86 }

 87 void update(int l,int r,int o,int ua,int ub)

 88 {

 89     if (ua <= l && ub >= r)

 90     {

 91         if (op[0] == 'N')

 92         {

 93             maxv[o] = -maxv[o];

 94             minv[o] = -minv[o];

 95             swap(maxv[o],minv[o]);

 96             lazy[o] ^= 1;

 97         }

 98         if (op[0] == 'C')

 99             minv[o] = maxv[o]  = val,lazy[o] = 0;

100         return;

101     }

102     //if (op[0] == 'N')

103     push_down(l,r,o);

104     int mid = (l + r) >> 1;

105     if (ua <= mid)

106         update(l,mid,o<<1,ua,ub);

107     if (ub > mid)

108         update(mid+1,r,o<<1|1,ua,ub);

109     minv[o] = min(minv[o<<1],minv[o<<1|1]);

110     maxv[o] = max(maxv[o<<1],maxv[o<<1|1]);

111 }

112 

113 int query(int l,int r,int o,int ua,int ub)

114 {

115     if (ua <= l && ub >= r)

116         return maxv[o];

117     int mid = (l + r) >> 1;

118     push_down(l,r,o);

119     int t1 = -inf,t2 = -inf;

120     if (ua <= mid)

121         t1 = query(l,mid,o<<1,ua,ub);

122     if (ub > mid)

123         t2 = query(mid+1,r,o<<1|1,ua,ub);

124     minv[o] = min(minv[o<<1],minv[o<<1|1]);

125     maxv[o] = max(maxv[o<<1],maxv[o<<1|1]);

126     return max(t1,t2);

127 }

128 

129 int get_max(int ua,int ub)

130 {

131     int f1 = top[ua];

132     int f2 = top[ub];

133     int tmp = -inf;

134     while (f1 != f2)

135     {

136         if (dep[f1] < dep[f2])

137             swap(ua,ub),swap(f1,f2);

138         tmp = max(tmp,query(1,tot,1,pos[f1],pos[ua]));

139         ua = fa[f1];

140         f1 = top[ua];

141     }

142     if (ua == ub)

143         return tmp;

144     if (dep[ua]  > dep[ub])

145         swap(ua,ub);

146     return tmp = max(tmp,query(1,tot,1,pos[son[ua]],pos[ub]));

147 }

148 void get_negate(int ua,int ub)

149 {

150     int f1 = top[ua];

151     int f2 = top[ub];

152     while (f1 != f2)

153     {

154         if (dep[f1] < dep[f2])

155             swap(ua,ub),swap(f1,f2);

156         update(1,tot,1,pos[f1],pos[ua]);

157         ua = fa[f1];

158         f1 = top[ua];

159     }

160     if (dep[ua] > dep[ub])

161         swap(ua,ub);

162     if (ua == ub)

163         return;

164     update(1,tot,1,pos[son[ua]],pos[ub]);

165 }

166 

167 int d[maxn][3];

168 void init()

169 {

170     int root,n;

171     scanf ("%d",&n);

172     root = (n + 1) >> 1;

173     edge = tot = 1;

174     memset(siz,0,sizeof(siz));

175     memset(head,0,sizeof(head));

176     fa[root] = dep[root] = 0;

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

178     {

179         scanf ("%d%d%d",&d[i][0],&d[i][1],&d[i][2]);

180         add(d[i][1],d[i][0]);

181         add(d[i][0],d[i][1]);

182     }

183     dfs(root);

184     build(root,root);

185     build_Segtree(1,tot,1);

186     op[0] = 'C';

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

188     {

189         if (dep[d[i][0]] < dep[d[i][1]])

190             swap(d[i][0],d[i][1]);

191         tt[d[i][0]] = val = d[i][2];

192         update(1,tot,1,pos[d[i][0]],pos[d[i][0]]);

193     }

194 }

195 int main(void)

196 {

197     freopen("in.txt","r",stdin);

198     int t;

199     scanf ("%d",&t);

200     while (t--)

201     {

202         init();

203         while (scanf ("%s",op),op[0] != 'D')

204         {

205             int x,y;

206             scanf ("%d%d",&x,&y);

207             if (op[0] == 'Q'&&x!=y)

208                 printf("%d\n",get_max(x,y));

209             if (op[0] == 'Q' && x == y)

210                 printf("0\n");

211             if (op[0] == 'C')

212             {

213                 val = y;

214                 update(1,tot,1,pos[d[x][0]],pos[d[x][0]]);

215             }

216             if (op[0] == 'N'&&x!=y)

217                 get_negate(x,y);

218         }

219     }

220     return 0;

221 }

222 

223 

224 /*

225 1

226 11

227 2 1 1

228 2 4 2

229 2 3 3

230 1 5 4

231 3 6 5

232 3 7 6

233 7 8 7

234 4 9 8

235 9 10 9

236 10 11 10

237 N 2 10

238 Query 4 10

239 DONE

240 

241 */

 

你可能感兴趣的:(tree)