A tree is a simple graph in which every two vertices are connected by exactly one path. You are given a rooted tree with vertices and a lamp is placed on each vertex of the tree.
You are given queries of the following two types:
1 v: You switch the lamp placed on the vertex v, that is, either from On to Off or Off to On.
2 v: Determine the number of vertices connected to the subtree of v if you only consider the lamps that are in On state. In other words, determine the number of vertices in the subtree of v , such as u, that can reach from v by using only the vertices that have lamps in the On state.
Note: Initially, all the lamps are turned On and the tree is rooted from vertex number .
Input format
First line: Two integers and denoting the number of vertices and queries Next lines: Two number and denoting an edge between the vertices and Next lines: Two integers and , where is the type of the query Note: It is guaranteed that these edges form a tree rooted from vertex .
Output format For every query of type 2, print the answer in a single line.
Constraints
SAMPLE INPUT
5 4
1 2
2 3
1 4
4 5
1 3
2 2
1 3
2 2
SAMPLE OUTPUT
1
2
Explanation:
This is the tree in the first place:
The tree after turning off lamp in node Obviously the answer now for vertex is
Code:
void updateSubSwitches(vector<vector<int>> &tree,vector<int> &parent, vector<int> &switchesSubTree, int vertex, bool flag) {
if(flag) {
switchesSubTree[vertex]=1;
for(int i=0;i<tree[vertex].size();i++) {
switchesSubTree[vertex] += switchesSubTree[tree[vertex][i]];
}
int parentVertex=parent[vertex];
while(switchesSubTree[parentVertex]!=0 && parentVertex!=0) {
switchesSubTree[parentVertex]=switchesSubTree[parentVertex]+switchesSubTree[vertex];
parentVertex=parent[parentVertex];
}
if(parentVertex == 0) {
switchesSubTree[0]=switchesSubTree[0]+switchesSubTree[vertex];
}
} else {
int parentVertex=parent[vertex];
while(switchesSubTree[parentVertex]!=0 && parentVertex!=0) {
switchesSubTree[parentVertex]=switchesSubTree[parentVertex]-switchesSubTree[vertex];
parentVertex=parent[parentVertex];
}
if(parentVertex == 0) {
switchesSubTree[0]=switchesSubTree[0]-switchesSubTree[vertex];
}
switchesSubTree[vertex]=0;
}
}
int initialSubSwitches(vector<vector<int>> &tree, vector<int> &switchesSubTree,int vertex) {
if(switchesSubTree[vertex] == -1) {
if(tree[vertex].size() > 0) {
switchesSubTree[vertex] = 1;
//cout<<vertex<<endl;
for(int i=0;i<tree[vertex].size();i++){
switchesSubTree[vertex] += initialSubSwitches(tree,switchesSubTree,tree[vertex][i]);
}
return switchesSubTree[vertex];
} else {
//cout<<vertex<<endl;
switchesSubTree[vertex] = 1;
return 1;
}
}
}
int main() {
int n,q;
cin>>n>>q;
vector<vector<int>> tree(n);
vector<bool> arr(n,true);
vector<int> switchesSubTree(n,-1);
vector<int> parent(n);
for(int i=1;i<=n-1;i++) {
int a,b;
cin>>a>>b;
tree[a-1].push_back(b-1);
parent[b-1] = a-1;
}
initialSubSwitches(tree,switchesSubTree,0);
for(int i=1;i<=q;i++) {
int b,v;
cin>>b>>v;
if(b==1) {
arr[v-1]=!arr[v-1];
updateSubSwitches(tree,parent,switchesSubTree,v-1,arr[v-1]);
} else {
cout<<switchesSubTree[v-1]<<endl;
}
}
}
Algorithm:
Initialization
- tree stores the graph
- arr stores if lamp at vertex v is ON or OFF.
- switchesSubTree stores the number of lamps swtiched ON for that subtree.
Steps:
1. initialize the switchesSubTree array if initially all lamps are ON.
2. For each query,
2.1 if lamp is turned OFF:
decrease its ancestors by switchesSubTree[vertex] until we get a node whose lamp is OFF or we reach root vertex
make switchesSubTree[vertex] = 0
2.2 if lamp is turned ON:
calculate no. of lamps swithced ON for this vertex which is
switchesSubTree[vertex] = 1 + sum(all lamps of children)
increase the lamps for ancestors until we get a node whose lamp is OFF or we reach root vertex.
But solution gives TIME LIMIT EXCEEDED for some test cases and also wrong for some test cases. Where am I going wrong and what can be an efficient and better solution ?