Problem
Test instructions
- Given a tree, and given two operations on this tree. One operation is to change the weights of one node, and the other is to count the weights on the path between the two nodes, if each weight is an even number, output-1, or the number of output occurrences is an odd amount of weight (guaranteed only one)
Ideas
- This problem is a template problem for DFS sequences. The first thought is that we get the DFS order for this tree, and for this sequence we can go and maintain the XOR of the interval. Because it is a single point to modify the interval query, you can use a tree-like array can also be directly written line segment tree. Then for each inquiry, we query each point to the root of the XOR and (here directly with the DFS sequence to the root node of the XOR and can be, because if a node is not on its path to the root node, it will appear two times, XOR and 0), and then find the two nodes of the LCA, re-or LCA weights. Note this place, if a node weight value is 0, an error occurs. So this is going to be handled (add 1 to the weight, minus 1 for the answer). The method of multiplication, Tarjan and RMQ can be used for LCA.
- This question hdu slightly pit, turn g++ has been exploding stack. But there's no need to take care of this. Cross C + + is over.
AC Code
#include <iostream>#include <cstdio>#include <vector>#include <algorithm>#include <cstring>#include <cmath>#define Lson l,m,rt<<1#define Rson m+1,r,rt<<1|1using namespace STD;Const intMAXN =110000;intcnt,head[maxn],dep[maxn],p[maxn][ -],tot;intST[MAXN],ED[MAXN];intsum[maxn<<3];intN,q;voidUpdateintPosintCintLintRintRT) {if(L = = r) {SUM[RT] = C;return; }intm = (l+r) >>1;if(POS <= m) update (Pos,c,lson);ElseUpdate (Pos,c,rson); SUM[RT] = sum[rt<<1] ^ sum[rt<<1|1];}intQueryintLintRintLintRintRT) {if(L>=l && r>=r) {returnSUM[RT]; }intRET =0;intm = (l+r) >>1;if(L <= m) Ret ^= query (L,r,lson);if(R > m) RET ^= query (L,r,rson);returnRET;}structedge{intU,v;intNext;} e[maxn<<1];voidAddedge (intUintV) {e[cnt].u = U,E[CNT].V = V,e[cnt].next = Head[u],head[u] = cnt++; e[cnt].u = V,E[CNT].V = U,e[cnt].next = Head[v],head[v] = cnt++;}voidDfsintu) {st[u] = tot++; for(inti=head[u];i!=-1; i=e[i].next) {intv = e[i].v;if(!dep[v]) {Dep[v] = Dep[u] +1; p[v][0] = u; DFS (v); }} Ed[u] = tot++;}voidInit () {cnt =0; tot =1;memset(head,-1,sizeof(head));memset(p,-1,sizeof(p));memset(DEP,0,sizeof(DEP));}intLCA (intAintb) {if(Dep[a]<dep[b]) swap (A, b);intI for(i =0;(1<<i) <=dep[a];i++); i--; for(intj=i;j>=0; j--)if(Dep[a]-(1<<J) >=dep[b]) a = p[a][j];if(A = = b)returnA for(intj=i;j>=0; j--) {if(p[a][j]!=-1&& p[a][j]! = P[b][j]) {a = P[a][j]; b = P[b][j]; } }returnp[a][0];}intU,v;intMain () {intTCin>>T; while(t--) {scanf("%d%d", &n,&q); Init (); for(intI=0; i<n-1; i++) {scanf("%d%d", &u,&v); Addedge (U,V); } dep[1] =1; Dfs1); for(intj=1;(1<<J) <=n;j++) for(intI=1; i<=n;i++)if(p[i][j-1] != -1) P[i][j] = p[p[i][j-1]][j-1]; tot--;memset(Sum,0,sizeof(sum));//for (int i=1;i<=n;i++) printf ("%d", St[i]); //printf ("Tot:%d\n", tot); for(intI=1; i<=n;i++) {scanf("%d", &u); Update (st[i],u+1,1Tot1), Update (ed[i],u+1,1Tot1); } while(q--) {intOp,x,y;scanf("%d%d%d", &op,&x,&y);if(OP = =0) {Update (st[x],y+1,1Tot1), Update (ed[x],y+1,1Tot1); }Else{intANSX = Query (1, St[x],1Tot1), Ansy = Query (1, St[y],1Tot1);intLCA = LCA (x, y), Anslca =query (St[lca],st[lca],1Tot1);//printf ("ansx:%d ansy:%d lca:%d\n", ANSX,ANSY,LCA); intAns = ansx ^ Ansy ^ anslca;if(ans = =0)puts("-1");Else printf("%d\n", ans-1); } } }return 0;}
Bestcoder #45 1003 Dylans loves tree