[Codechef - AASHRAM] Gaithonde Aashram Leaves
Description
Given a tree, "N" node tree rooted in a node, each node 'u' and the weight a [u] is associated. You can also perform two types of queries in the trees. The number of queries is 'M'.
1 U Val: 1 for the query type, the nodes will be given a 'U' and an integer Val. = Subtree and set (including the 'U') in the subtree weightings sum of all the nodes. If the node 'U' subtree and add a sum is even, then each node Val 'U' subtree (nodes comprising 'U'), otherwise 1 is added to each node of the subtree (nodes comprising 'U').
2 UV: 2 type of the query will be given two nodes 'U' and 'V', and must be printed 'U' and 'V' and subtree bit XOR.
Solution
DFS order to do it.
SB I put the main program with anti-DFS results actually had a sample ......
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
namespace seg
{
int val[N],tag[N];
void pushup(int p)
{
val[p]=val[p*2]+val[p*2+1];
}
void pushdown(int p,int l,int r)
{
if(tag[p])
{
tag[p*2]+=tag[p];
tag[p*2+1]+=tag[p];
val[p*2]+=tag[p]*((l+r)/2-l+1);
val[p*2+1]+=tag[p]*(r-(l+r)/2);
tag[p]=0;
}
}
void build(int p,int l,int r,int *src)
{
if(l==r)
{
val[p]=src[l];
}
else
{
build(p*2,l,(l+r)/2,src);
build(p*2+1,(l+r)/2+1,r,src);
pushup(p);
}
}
void modify(int p,int l,int r,int ql,int qr,int v)
{
if(l>qr || r<ql)
return;
if(l>=ql && r<=qr)
{
val[p]+=v*(r-l+1);
tag[p]+=v;
}
else
{
pushdown(p,l,r);
modify(p*2,l,(l+r)/2,ql,qr,v);
modify(p*2+1,(l+r)/2+1,r,ql,qr,v);
pushup(p);
}
}
int query(int p,int l,int r,int ql,int qr)
{
if(l>qr || r<ql)
return 0;
if(l>=ql && r<=qr)
return val[p];
else
{
pushdown(p,l,r);
return query(p*2,l,(l+r)/2,ql,qr) + query(p*2+1,(l+r)/2+1,r,ql,qr);
}
}
}
namespace tree
{
vector <int> g[N];
int dfn[N],fin[N],vis[N],ind=0,n;
void link(int p,int q)
{
g[p].push_back(q);
g[q].push_back(p);
}
void dfs(int p)
{
vis[p]=1;
dfn[p]=++ind;
for(int i=0; i<g[p].size(); i++)
{
if(vis[g[p][i]]==0)
{
dfs(g[p][i]);
}
}
fin[p]=ind;
}
void presolve()
{
memset(vis,0,sizeof vis);
dfs(1);
}
int query(int p)
{
return seg::query(1,1,n,dfn[p],fin[p]);
}
void modify(int p,int v)
{
seg::modify(1,1,n,dfn[p],fin[p],v);
}
}
int n,m,t1,t2,t3,t4;
int v[N],src[N];
signed main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1; i<=n; i++)
{
cin>>v[i];
}
for(int i=1; i<n; i++)
{
cin>>t1>>t2;
tree::link(t1,t2);
}
tree::presolve();
tree::n=n;
for(int i=1; i<=n; i++)
{
src[tree::dfn[i]]=v[i];
}
seg::build(1,1,n,src);
for(int i=1; i<=m; i++)
{
cin>>t1>>t2>>t3;
if(t1==1)
{
if(tree::query(t2)%2ll)
{
tree::modify(t2,1);
}
else
{
tree::modify(t2,t3);
}
}
else
{
cout<<(tree::query(t2) ^ tree::query(t3))<<endl;
}
}
}