Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

并查集实现的线性RMQ,大家来讨论一下如何更快把

Posted by dut200901102 at 2012-10-07 18:59:30 on Problem 3264 and last updated at 2012-10-07 19:00:45
离线操作,用并查集维护每个点到当前点所构成区间的最值。
code:
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 50010;
const int Q = 200010;
struct Node{
	int to, idx, next;
}e[Q];
int n, q, maxV[N], minV[N], p[N], ans[Q], box[N], size;

inline void add(int from, int to, int idx){
	e[size].to = to;
	e[size].idx = idx;
	e[size].next = box[from];
	box[from] = size++;
}
void init(){
	scanf("%d %d", &n, &q);
	for(int i = 1; i <= n; ++i){
		scanf("%d", &maxV[i]);
		minV[i] = maxV[i];
		p[i] = i;
	}
	memset(box, -1, sizeof(box)), size = 0;
	for(int i = 0, x, y; i < q; ++i){
		scanf("%d %d", &x, &y);
		add(y, x, i);
	}
}
inline int find(int x){
	int px = p[x];
	if(p[x] != x){
		p[x] = find(p[x]);
		maxV[x] = max(maxV[x], maxV[px]);
		minV[x] = min(minV[x], minV[px]);
	}
	return p[x];
}	
void solve(){
	for(int i = 1; i <= n; ++i){
		for(int j = box[i]; ~j; j = e[j].next){
			int l = e[j].to;
			find(l);
			ans[e[j].idx] =  maxV[l] - minV[l];
		}
		p[i] = i + 1;
	}
	for(int i = 0; i < q; ++i)
		printf("%d\n", ans[i]);
}
int main(){
	init();
	solve();
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator