[AOJ 2170]Marked Ancestor[并查集][离线][路径压缩]or[线段树]
来源:互联网 发布:淘宝企业店铺开店资料 编辑:程序博客网 时间:2024/05/01 16:41
题目链接:[AOJ 2170]Marked Ancestor[并查集][离线][路径压缩]or[线段树]
线段树君(队友代码):
题意分析:
结点1为根结点,初始时已经染过颜色。给出N - 1行,第i行代表第i + 1个结点的父亲结点是哪个结点。
现在给出最多1e5个结点,1e5个查询。查询操作分两种,Q X代表查询结点X的最近的被染色的父或者祖先结点被染色的编号,M X代表对结点X染色。
问:所有查询完之后,Q查询的编号值之和为多少?
解题思路:
最坏情况下为整棵树成为一条链,单纯使用并查集查询复杂度最坏1e10。然而单纯使用并查集也能过,这题估计数据水。(或者谁告诉我下,1e10八秒是无压力跑的,那我也就没什么意见了。)
正解应该是将查询存下来,存下每次Q操作的查询时间和查询结点,用qt和qv数组存储。另外设置mark数组存储这个结点被染色的最快时间。然后我们倒着进行查询操作,当当前查询的结点最早被染色时间小于当前时间时,就可以返回这个结点了,否则进行路径压缩(进入否则,说明这个结点的最快被染色时间大于查询时间,而我们是倒着进行操作的,说明后继的查询时间都比当前的查询时间小,不管怎么样,这个结点都不会被染色了,无用,直接拿来压缩掉)
还有一种解法就是使用线段树来解这道题,利用dfs序来维护。具体是队友做出来了,我也不大懂怎么搞= =,膜拜ORZ 具体做法见下↓
个人感受:
1e10啊!!!!第一次做的时候不管三七二十一就最简单的find函数去上交,竟然A了。
想想这个复杂度不对啊,查题解各种涨姿势ORZ ORZ ORZ 当时现场赛的同学一定是崩溃的= =
具体代码如下:
并查集君:
#include<cstdio>#include<iostream>#define ll long longusing namespace std;const int INF = 0x7f7f7f7f;const int MAXN = 1e5 + 111;int p[MAXN];int qt[MAXN], qv[MAXN], mark[MAXN];int t;int find(int x) { return mark[x] < t ? x : p[x] = find(p[x]); // 小于则说明在查询之前已经染过颜色}int main(){ int n, q; while (~scanf("%d%d", &n, &q) && (n | q)) { for (int i = 2; i <= n; ++i) { scanf("%d", p + i); mark[i] = INF; } int cnt = 0, x; char op[2]; for (int i = 1; i <= q; ++i) { scanf("%s%d", op, &x); if (op[0] == 'M') mark[x] = min(mark[x], i); // 记录最早染色时间 else { qt[cnt] = i; qv[cnt++] = x; } } ll ans = 0; while (cnt --) { t = qt[cnt]; // 查询发生的时间 ans += find(qv[cnt]); } printf("%lld\n", ans); } return 0;}
线段树君(队友代码):
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <string>#include <queue>#include <cstdlib>#include <algorithm>#include <stack>#include <map>#include <queue>#include <vector>using namespace std;const int maxn = 1e5+100;const int INF = 0x3f3f3f3f;#define pr(x) // cout << #x << " = " << x << " ";#define prln(x) // cout << #x << " = " << x <<endl;#define ll long longint head[maxn], nxt[maxn], to[maxn], dfsn, cnt, id[maxn], r[maxn], _n, sum[maxn<<2], dep[maxn];void addedge(int u, int v) {nxt[cnt] = head[u];head[u] = cnt;to[cnt++] = v;}void init(int n) {cnt = dfsn = 0;_n = 1;while(_n < n) _n = _n*2;int _nn = _n*2;for(int i = 0; i <= _nn; ++i) sum[i] = -1;for(int i = 0; i <= n;++i) {head[i] =-1;}}void dfstree(int fa,int u) {id[u] = ++dfsn;dep[u] = dep[fa]+1;for(int i = head[u]; ~i; i = nxt[i]){dfstree(u,to[i]);}r[u] = dfsn;}inline void getans(int& ans, const int& v2){if(ans == -1 || dep[ans] < dep[v2]) ans = v2;}void pushdown(int rt) {if(sum[rt] != -1) {getans(sum[rt<<1], sum[rt]);getans(sum[rt<<1|1],sum[rt]);}}void update(int rt, int l, int r, int ql, int qr, int v) {if(ql <= l && r <= qr) {getans(sum[rt], v);return;}pushdown(rt);int m = l + r >> 1;if(m >= ql) update(rt<<1, l, m, ql, qr, v);if(m < qr) update(rt<<1|1, m+1, r, ql, qr, v);}int query(int rt) {rt += _n-1;int ans = 0;while(rt>=1) {getans(ans,sum[rt]);rt = rt>>1;}return ans;}int main(){#ifdef LOCAL freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin); //freopen("C:\\Users\\Administrator\\Desktop\\out.txt","w",stdout); #endif int n, m, x; char op[10]; while(cin >> n >> m && (n||m)) { ll ans = 0; init(n); for(int i = 2; i <= n; ++i) { scanf("%d", &x); addedge(x,i); } dep[0] = 0; dfstree(0,1); update(1, 1, _n, id[1], r[1], 1); for(int i = 0; i < m; ++i) { scanf("%s%d", op, &x); if(op[0] == 'M')update(1, 1, _n, id[x], r[x], x); elseans += query(id[x]); } printf("%lld\n", ans); } return 0;}
0 0
- [AOJ 2170]Marked Ancestor[并查集][离线][路径压缩]or[线段树]
- AOJ 2170 Marked Ancestor (并查集)
- Marked Ancestor (AOJ 2170 并查集)
- Aizu 2170 Marked Ancestor【并查集】
- AOJ2170 Marked Ancestor 并查集
- 并查集 AOJ 2170
- poj1456 并查集or线段树
- sicily 1876. Basic Graph Problem 线段树+并查集+路径压缩
- 并查集 & 路径压缩
- 【并查集+压缩路径】
- 并查集路径压缩
- 并查集路径压缩
- 并查集路径压缩
- 并查集路径压缩
- 并查集压缩路径
- 并查集 压缩路径
- 并查集路径压缩
- 并查集 ---压缩路径
- 尝试使用request.getRemoteAddr()时获得ipv6地址:0.0.0.0.0.0.0.1的解决方法
- 初探Android Scroll——scrollTo()与scrollBy()
- Mybatis学习(1)开发环境搭建
- RPC总结 ---发文于2013-12-20
- CSS学习笔记14-非屏幕媒体
- [AOJ 2170]Marked Ancestor[并查集][离线][路径压缩]or[线段树]
- 遇到一个把.o文件strip后出现的奇怪问题
- leetcode165---Compare Version Numbers
- [乡土民间故事_徐苟三传奇]第四回_张员外受骗摔新锅
- Android开源框架Universal-Image-Loader基本介绍和使用
- ndis协议驱动总结---发文于2013-12-30
- httpclient 4.3.x 版本 post 中文乱码问题
- java代码创建文件和文件夹
- ndis小端口驱动总结---发文于2014.1.1