0

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:

enter image description here

The tree after turning off lamp in node Obviously the answer now for vertex is

enter image description here

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

  1. tree stores the graph
  2. arr stores if lamp at vertex v is ON or OFF.
  3. 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 ?

Olivia Pearls
  • 139
  • 1
  • 11
  • I couldn't understand what the problem asks exactly and I couldn't understand what the queries do. – Daniel Jul 11 '20 at 20:37
  • It sounds like query type `1` toggles the lamp state, and query type `2` returns the number of "on" lamps beneath and including the specified node? And TLE stands for "time limit exceeded"? The best way to debug this is to look specifically at the test cases that are failing and walk through your code (with pencil and paper) to understand where it's not returning what you expect. For the cases that exceed their time limits, consider ways to make your algorithm more efficient. – Welbog Jul 11 '20 at 21:20
  • 1
    It looks like this is copied and pasted from https://www.hackerearth.com/de/practice/data-structures/advanced-data-structures/segment-trees/practice-problems/algorithm/tree-query-3-5d98588f/, though with some transcription errors (missing notation in a few places). – Welbog Jul 11 '20 at 21:23
  • Skimming the code you have, it looks logical to me. It seems efficient (modifications to the tree happen in O(lg(n)) time in the average case), and seems correct. I would need to see a specific example that's failing to understand the problem. It's probably an edge case of some kind. – Welbog Jul 11 '20 at 21:42

0 Answers0