时间限制: 1Sec 内存限制: 128MB 提交: 5 解决: 0
题目描述
作为 drd 送的生日礼物,atm 最近得到了一个俄罗斯娃娃。他对这个俄罗斯娃娃的构造很感兴趣。
俄罗斯娃娃是一层一层套起来的。假设:一个大小为 x 的俄罗斯娃娃里面可能会放任意多个大小小于 x 的俄罗斯娃娃(而市场上的套娃一般大娃里只能放一个小娃)。
drd 告诉 atm ,这个俄罗斯娃娃是由 n 个小娃娃组成的,它们的大小各不相同。 我们把这些小娃娃的大小从小到大依次记为 1 到 n 。
如果 atm 想观赏大小为 k 的小娃娃,他会先看这个小娃娃是否已经在桌子上了。 如果已经在桌子上,那么他就可以观赏了。否则他就打开桌子上某一个俄罗斯娃娃,将它套住的所有的小娃娃拿出来,摆在桌子上。
一开始桌子上只有 drd 送的大小为 n 的娃娃。注意,他只会将其中所有小娃娃拿出来,如果小娃娃里面还套着另外的小娃娃,他是不会将这些更里层的这些小娃娃拿出来的。
而且 atm 天生具有最优化的强迫症。他会最小化他所需要打开的娃娃的数目。
atm 是一个怪人。有时候他只想知道观看大小为 x 的娃娃时需要打开多少个娃娃(但并不去打开);有时候听 drd 说某个娃娃特别漂亮,于是他会打开看。现在请你输出他每次需要打开多少个娃娃。
输入
第一行两个数 n m ,表示娃娃的数目以及 atm 想看的娃娃的数目。
接下来 n - 1 行,每行两个数 u v,表示大小为 u 的娃娃里面套着一个大小为 v 的娃娃。保证 u > v 。
接下来 m 行,每行形如:
P x :表示 atm 一定要看到大小为 x 的娃娃;
Q x :表示 atm 只想知道为了看大小为 x 的娃娃,他需要打开多少个娃娃,但实际上并不打开他们。
接下来 n - 1 行,每行两个数 u v,表示大小为 u 的娃娃里面套着一个大小为 v 的娃娃。保证 u > v 。
接下来 m 行,每行形如:
P x :表示 atm 一定要看到大小为 x 的娃娃;
Q x :表示 atm 只想知道为了看大小为 x 的娃娃,他需要打开多少个娃娃,但实际上并不打开他们。
输出
输出 m 行。对应输入中P操作或Q操作需要打开(或假想打开)多少个俄罗斯娃娃。
样例输入
5 5 5 3 5 4 3 2 3 1 Q 1 Q 4 P 2 Q 1 Q 4
样例输出
2 1 2 0 0
#include<iostream> #include<algorithm> #include<queue> #include<vector> using namespace std; const int maxn = 1000010; struct Node{ int depth; vector<int>next; int pre; }nodes[maxn]; int n,m; void update(int index); int main(void) { cin >> n >> m; for(int i=1;i<=n;i++) { nodes[i].depth = 0; nodes[i].pre = i; } for(int i=0;i<n-1;i++) { int u,v; cin >> u >> v; nodes[v].pre = u; nodes[u].next.push_back(v); } for(int i=1;i<=n;i++) { int depth = 0,k=i; while(nodes[k].pre!=k) { depth++; k = nodes[k].pre; } nodes[i].depth = depth; } /* cout << endl; for(int i=1;i<=n;i++) { cout << nodes[i].depth<<" "; } cout << endl; */ for(int i=1;i<=m;i++) { string cm; int index; cin >> cm >> index; cout <<nodes[index].depth; if(i!=m) cout << endl; if(cm[0]=='P') { if(nodes[index].depth==0) { } else { //将本节点和所有父节点保存 vector<int>father; int k = i; while(nodes[k].pre!=k) { father.push_back(k); int temp = k; k = nodes[k].pre; nodes[temp].pre = temp; } father.push_back(k); //从最上次的节点开始,进行更新,每次更新需要把自己的后继节点全部释放 int size = father.size(); for(k=0;k<size;k++) { update(father[size-1-k]); } } } /* cout << endl; for(int k=1;k<=n;k++) { cout << nodes[k].depth<<" "; } cout << endl; */ } return 0; } void update(int index) { queue<int>que; for(int i=0;i<nodes[index].next.size();i++) { que.push(nodes[index].next[i]); } nodes[index].next.clear(); while(!que.empty()) { int u = que.front(); que.pop(); nodes[u].depth--; if(nodes[u].depth==0) nodes[u].pre = u; for(int i=0;i<nodes[u].next.size();i++) { que.push(nodes[u].next[i]); } } }
这是错误的,当然可能是正确的,但是时间复杂度太高了。