Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
并查集实现的线性RMQ,大家来讨论一下如何更快把离线操作,用并查集维护每个点到当前点所构成区间的最值。 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: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator