BestCoder #45 1003 Dylans loves tree,
Problem
Question
- Specify a tree and two operations on the tree. One operation is to change the weight of a node, and the other operation is to calculate the weight of the path between two nodes. If each weight value appears an even number of times, output-1; otherwise, the output has an odd weight (ensure only one)
Ideas
- This is a DFS sequence template question. First, we can obtain the DFS sequence of the tree. For this sequence, we can maintain the variance or sum of intervals. Because it is a single-point modification interval query, you can use a tree array or directly write a line segment tree. Then, for each query, We can query the variance or sum between each point and the root node (here we can directly use the variance or sum from the DFS sequence to the root node, because if a node is not in its path to the root node, it will appear twice, an exception or a sum of 0), and then find the LCA of the two nodes, returns the same or the value of LCA. Note that an error occurs if the weight of a node is 0. So here we need to deal with it (add 1 to all weights and 1 to the output answer ). You can use the multiplication method, Tarjan, and RMQ for the LCA.
- HDU is a little pitfall, And the stack has been exploding with G ++. However, there is no need to worry about this .. It's time to pass in C ++.
- The stack opening code of G ++ is used to successfully access the AC under G ++ ..
AC code
G ++ stack opening code
register char *_sp __asm__("rsp");int main(){ const int size = 64*1024*1024; static char *sys,*mine(new char[size]+size-4096); sys = _sp;_sp = mine;mmain();_sp = sys; return 0;}
#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 int MAXN = 110000;int cnt,head[MAXN],dep[MAXN],p[MAXN][20],tot;int st[MAXN],ed[MAXN];int sum[MAXN<<3];int n,q;void update(int pos,int c,int l,int r,int rt){ if(l == r){ sum[rt] = c; return; } int m = (l+r)>>1; if(pos <= m)update(pos,c,lson); else update(pos,c,rson); sum[rt] = sum[rt<<1] ^ sum[rt<<1|1];}int query(int L,int R,int l,int r,int rt){ if(l>=L && R>=r){ return sum[rt]; } int ret = 0; int m = (l+r)>>1; if(L <= m)ret ^= query(L,R,lson); if(R > m)ret ^= query(L,R,rson); return ret;}struct Edge{ int u,v; int next;}e[MAXN<<1];void addedge(int u,int v){ 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++;}void dfs(int u){ st[u] = tot++; for(int i=head[u];i!=-1;i=e[i].next){ int v = e[i].v; if(!dep[v]){ dep[v] = dep[u] + 1; p[v][0] = u; dfs(v); } } ed[u] = tot++;}void init(){ cnt = 0; tot = 1; memset(head,-1,sizeof(head)); memset(p,-1,sizeof(p)); memset(dep,0,sizeof(dep));}int LCA(int a,int b){ if(dep[a]<dep[b])swap(a,b); int i; for(i = 0;(1<<i)<=dep[a];i++); i--; for(int j=i;j>=0;j--) if(dep[a]-(1<<j)>=dep[b]) a = p[a][j]; if(a == b)return a; for(int j=i;j>=0;j--){ if(p[a][j]!=-1 && p[a][j] != p[b][j]){ a = p[a][j]; b = p[b][j]; } } return p[a][0];}int u,v;int main(){ int T; cin>>T; while(T--){ scanf("%d%d",&n,&q); init(); for(int i=0;i<n-1;i++){ scanf("%d%d",&u,&v); addedge(u,v); } dep[1] = 1; dfs(1); for(int j=1;(1<<j)<=n;j++) for(int i=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(int i=1;i<=n;i++){ scanf("%d",&u); update(st[i],u+1,1,tot,1),update(ed[i],u+1,1,tot,1); } while(q--){ int op,x,y; scanf("%d%d%d",&op,&x,&y); if(op == 0){ update(st[x],y+1,1,tot,1),update(ed[x],y+1,1,tot,1); }else{ int ansx = query(1,st[x],1,tot,1),ansy = query(1,st[y],1,tot,1); int lca = LCA(x,y),anslca =query(st[lca],st[lca],1,tot,1); //printf("ansx:%d ansy:%d lca:%d\n",ansx,ansy,lca); int ans = ansx ^ ansy ^ anslca; if( ans == 0)puts("-1"); else printf("%d\n",ans-1); } } } return 0;}