树是一个简单的图形,其中每两个顶点通过一条路径连接在一起。您将得到一棵有顶点的有根树,并且在树的每个顶点上都放置一盏灯。
系统会为您提供以下两种类型的查询:
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.
注意:最初,所有灯都已打开,并且树是从顶点号植根的。
输入格式
第一行:两个整数,表示顶点和查询的数量 下一行:两个数字,表示顶点和 下一行:两个整数和,其中查询的类型 注意:保证这些边缘形成以顶点为根的树。
输出格式 对于类型2的每个查询,将答案打印在一行中。
约束
SAMPLE INPUT
5 4
1 2
2 3
1 4
4 5
1 3
2 2
1 3
2 2
SAMPLE OUTPUT
1
2
说明:
这首先是树:
关闭节点中的灯后的树 显然,现在顶点的答案是
代码:
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;
}
}
}
算法:
初始化
步骤:
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.
但是对于某些测试用例,解决方案给出了超过时间限制的情况,对于某些测试用例也给出了错误的结果。 我在哪里做错了,什么是有效且更好的解决方案?