Aizu 2170 Marked Ancestor

来源:互联网 发布:网络推广的收费标准 编辑:程序博客网 时间:2024/05/23 14:05

刚看到题目感觉很简单,一开始我是直接按照输入的操作依次进行求解,写完之后提交超时。

代码如下:

#include<iostream>using namespace std;const int N = 100005;int a[2][N];long long sum;int find_ance(int index) {    if (a[1][index] == 1) {        return index;    }    else {        return find_ance(a[0][index]);    }}int main() {    int n, q;    char op;    int quest;    while (cin >> n >> q, n) {        sum = 0;        a[0][1] = 1;        a[1][1] = 1;        for (int i = 2; i <= n; ++i) {            cin >> a[0][i];            a[1][i] = 0;        }        cin >> op >> quest;        if (op == 'M') {            a[1][quest] = 1;        }        else {            sum += find_ance(quest);        }        cout << sum << endl;    }    return 0;}

由于自己也刚刚接触算法,也想不到要怎么样处理了,看了一下网上博客。其处理思想是:对于输入的操作,并不马上处理而是将操作按顺序存储,待全部操作如入完毕后,逆序处理输入的操作。同时,在逆序处理时伴随路径压缩。

因为查询操作与查询的时间以及标记生效的时间2方面有关,在输入时记录下查询的时间和标记的时间(没有做标记的默认为最大询问时间+1,根节点为0)。在find的时候根据询问的时间和标记生效时间进行搜索。

路径压缩会影响到答案吗?并不会,因为压缩的时候,标记一定已经失效了。

AC代码如下:

#include<iostream>#include<algorithm>using namespace std;const int N = 100005;int pre[N];     //存储节点之间的关系int marked[N];  //存储是否被标记以及标记的顺序int operation_order[N];     //按顺序存储输入的Q操作int operation_node_index[N];//存储Q操作针对的节点下标long long sum;int process_time;int find_ance(int index) {    if (marked[index] < process_time) {        return index;    }    else {        pre[index] = find_ance(pre[index]);        return pre[index];    }}int main() {    int n, q;    char op;    int index;    while (cin >> n >> q, n) {        sum = 0;        pre[1] = 1;        marked[1] = 0;        for (int i = 2; i <= n; ++i) {            cin >> pre[i];            marked[i] = q + 1;        }        int Q_operation_num = 0;        for (int i = 1; i <= q; ++i) {            cin >> op >> index;            if (op == 'Q') {                operation_order[Q_operation_num] = i;                operation_node_index[Q_operation_num++] = index;            }            else {                marked[index] = min(marked[index], i);            }        }        while (Q_operation_num--) {            process_time = operation_order[Q_operation_num];            sum += find_ance(operation_node_index[Q_operation_num]);        }        cout << sum << endl;    }    return 0;}
0 0
原创粉丝点击