Topic links: http://acm.hdu.edu.cn/showproblem.php?pid=6547
The meaning of problems: Given a tree, there are two modes of operation, the right path and query point, each point on the path square root rounded down.
Ideas: tree chain operations, 1e9 open up to 10 times the square root is 1, we only need to open a variable period of maintenance intervals are not all 1 on it.
#include " stdio.h " #include " string.h " #include " math.h " #include " algorithm " the using namespace STD; typedef Long Long LL; const int N = 200010 ; int n-, Q, the root, MOD; int head [N], Ver [N], the Next [N], TOT; /// tree structure storage LL Val [N]; /// storing information of each node int D [N], Son [N ], FAR [N], Size [N]; /// junction depth, heavy son, ancestors LL SUM [N * . 4 ];/// junction of line segment tree, maxx, sum value int DFN [N], top [N], id [N]; /// storage dfs order, top strand of ancestors, id each junction indexing position in the sequence of points in dfn int CNT; /// represents the last position dfs sequence int Laze [N * . 4 ], now [N * . 4 ]; int NUM [N * . 4 ]; void the Add ( int X, int Y) { /// add side of the tree Ver [TOT ++] = Y; the Next [TOT] = head [X]; head [X] = TOT; } void Build_Tree ( int ID, int L, int R & lt) { Laze [ID] = now [ID] =0; num[id] = 0; if(l == r) { laze[id] = 0; now[id] = 0; sum[id] = val[dfn[l]]; return ; } int mid = (l + r) >> 1; Build_Tree(id * 2,l,mid); Build_Tree(id * 2 + 1,mid + 1,r); sum[id] = sum[id * 2] + sum[id * 2 + 1]; return ; } void Update(int id,int L,int R,int l,int r)///将loc上的值进行更新 { if(l <= L && r >= R && num[id] >= 6) { return ; } if(L == R) { sum[id] = (ll)sqrt(sum[id]); num[id] ++; return ; } int mid = (L + R) >> 1; if(l <= mid) Update(id * 2,L,mid,l,r); if(r > mid) Update(id * 2 + 1,mid + 1,R,l,r); sum[id] = sum[id * 2] + sum[id * 2 + 1]; now[id] = min(now[id * 2],now[id * 2 + 1]); return ; } ll Query_sum(int id,int L,int R,int l,int r)///查询[l,r]区间和 { if(L > r || R < l) return 0; IF (L <= R & lt && L> = R & lt) { return SUM [ID]; } int MID = (L + R & lt) >> . 1 ; LL ANS = Query_sum (ID * 2 , L, MID, L, R & lt) Query_sum + (ID * 2 + . 1 , MID + . 1 , R & lt, L, R & lt); return ANS; } void DFS1 ( int U, int F, int DEP) /// DFS1 d array processing means, son array, far array, Size array { D [U] = DEP; FAR [U] = F; Size [U] = . 1 ; Son [U] = - . 1; for(int i = head[u]; i; i = Next[i]){ int v = ver[i]; if(v == f) continue; dfs1(v,u,dep+1); Size[u] += Size[v]; if(son[u] == -1 || Size[son[u]] < Size[v]) son[u] = v; } } void dfs2(int u,int T)///旨在处理重链,和dfs序列 { dfn[++ cnt] = u;id[u] = cnt; top[u] = T; if(son[u] == -1) return ; dfs2(son[u],T); for(int i = head[u]; i; i = Next[i]){ int v = ver[i]; if(v != son[u] && v != far[u]){ dfs2(v,v); } } } int main() { scanf("%d%d",&n,&q); for(int i = 1; i <= n; i ++) { scanf("%lld",&val[i]); } for(int i = 1; i < n; i ++) { int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } cnt = 0;root = 1; dfs1(root,root,1); dfs2(root,root); Build_Tree(1,1,n); while(q --) { int op; scanf("%d",&op); op ++; if(op == 1) { int u,v; scanf("%d%d",&u,&v); int fu = top[u],fv = top[v]; int ans = 0; while(fu != fv) { if(d[fu] >= d[fv]) { Update(1,1,n,id[fu],id[u]); u = far[fu]; fu = top[u]; } else { Update(1,1,n,id[fv],id[v]); v = far[fv]; fv = top[v]; } } if(id[u] < id[v]) Update(1,1,cnt,id[u],id[v]); else Update(1,1,cnt,id[v],id[u]); } if(op == 2) { int u,v; scanf("%d%d",&u,&v); int fu = top[u],fv = top[v]; ll ans = 0; while(fu != fv) { if(d[fu] >= d[fv]) { ans += Query_sum(1,1,n,id[fu],id[u]); u = far[fu]; fu = top[u]; } else { ans += Query_sum(1,1,n,id[fv],id[v]); v = far[fv]; fv = top[v]; } } if(id[u] < id[v]) ans += Query_sum(1,1,cnt,id[u],id[v]); else ans += Query_sum(1,1,cnt,id[v],id[u]); printf("%lld\n",ans); } } }