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 |
奇了怪了//#define __DEBUG #include <stdio.h> #include <queue> #include <stack> #include <deque> #include <vector> using namespace std; const int MAX = 65536; const int MAX_VALUE = (1 << 30); #define ASSERT(X, S) { if(!(X)) { S; int i = 0; i /= i; } } int min(int a, int b) { return a < b ? a : b; } int max(int a, int b) { return a < b ? b : a; } class line_tree { private: const static int SIZE = (((MAX - 1) << 2) - 1); class node { public: int lower_bound; int upper_bound; int max; int min; } n[SIZE]; int node_size; static inline int lc(int i) { return rc(i) - 1; } static inline int rc(int i) { return ((i + 1) << 1); } static inline int pc(int i) { return ((i - 1) >> 1); } static inline bool leaf(const node& i) { return i.lower_bound == i.upper_bound; } inline bool leaf(int i) { return leaf(n[i]); } static inline int mid(const node& i) { return ((i.lower_bound + i.upper_bound) >> 1); } inline int mid(int i) { return mid(n[i]); } static inline bool g_l(const node& i, int pos) { return mid(i) >= pos; } inline bool g_l(int i, int pos) { return g_l(n[i], pos); } static inline bool g_r(const node& i, int pos) { return !g_l(i, pos); } inline bool g_r(int i, int pos) { return g_r(n[i], pos); } static inline void push(queue<int>& q, int i, int l, int u) { ASSERT(l <= u, printf("insert %d with lower_bound = %d, upper_bound = %d\n", i, l, u)); q.push(i); q.push(l); q.push(u); } static inline void pop(queue<int>& q, int& i, int& l, int& u) { i = q.front(); q.pop(); l = q.front(); q.pop(); u = q.front(); q.pop(); } public: void clear() { for(int i = 0; i < node_size; i++) { n[i].min = MAX_VALUE; n[i].max = -MAX_VALUE; } } void create(int MAX) { node_size = 0; queue<int> q; push(q, 0, 0, MAX - 1); while(!q.empty()) { int i, l, u; pop(q, i, l, u); n[i].lower_bound = l; n[i].upper_bound = u; if(i >= node_size) node_size = i + 1; if(!leaf(i)) { #ifdef __DEBUG printf("adding node %d, [%d, %d]\n", lc(i), l, mid(i)); printf("adding node %d, [%d, %d]\n", rc(i), mid(i) + 1, u); #endif push(q, lc(i), l, mid(i)); push(q, rc(i), mid(i) + 1, u); } } clear(); #ifdef __DEBUG for(int i = 0; i < node_size; i++) { if(!leaf(n[pc(i)])) { if(i + 1 < node_size && pc(i) == pc(i + 1)) { ASSERT(n[i].upper_bound == n[i + 1].lower_bound - 1, printf("n[%d].upper_bound{%d} != n[%d].lower_bound{%d} - 1", i, n[i].upper_bound, i + 1, n[i + 1].lower_bound)); } if(i > 0) { ASSERT(n[i].lower_bound == n[pc(i)].lower_bound || n[i].upper_bound == n[pc(i)].upper_bound, printf("%d", i)); } } } #endif } void dump(int start, int end) { for(int i = 0; i < node_size; i++) { if((i == 0 || !leaf(pc(i))) && ((n[i].lower_bound >= start && n[i].lower_bound <= end) || (n[i].upper_bound >= start && n[i].upper_bound <= end))) printf("node[%d] [%d, %d] min = %d, max = %d\n", i, n[i].lower_bound, n[i].upper_bound, n[i].min, n[i].max); } } void insert(int pos, int v) { int i = 0; while(1) { if(n[i].min > v) n[i].min = v; if(n[i].max < v) n[i].max = v; if(leaf(n[i])) break; else if(g_l(n[i], pos)) i = lc(i); else i = rc(i); } } void insert(const vector<int>& values) { node_size = 0; queue<int> q; stack<int> s; push(q, 0, 0, values.size() - 1); while(!q.empty()) { int i, l, u; pop(q, i, l, u); n[i].lower_bound = l; n[i].upper_bound = u; if(leaf(i)) { n[i].min = values[l]; n[i].max = values[l]; if(i >= node_size) node_size = i + 1; } else { s.push(i); push(q, lc(i), l, mid(i)); push(q, rc(i), mid(i) + 1, u); } } while(!s.empty()) { int p = s.top(); s.pop(); n[p].min = min(n[lc(p)].min, n[rc(p)].min); n[p].max = max(n[lc(p)].max, n[rc(p)].max); } } void query(const int is, const int ie, int& min, int& max) { min = MAX_VALUE; max = -MAX_VALUE; queue<int> q; push(q, 0, is, ie); while(!q.empty()) { ASSERT(q.size() <= 5 * 3, printf("q.size() == %d\n", q.size())); int i; int start; int end; pop(q, i, start, end); #ifdef __DEBUG printf("query n[%d]{lower_bound == %d, upper_bound == %d, min == %d, max == %d} for range [%d, %d]\n", i, n[i].lower_bound, n[i].upper_bound, n[i].min, n[i].max, start, end); #endif if(n[i].lower_bound >= start && n[i].upper_bound <= end) { if(min > n[i].min) min = n[i].min; if(max < n[i].max) max = n[i].max; } else if(n[i].min < min || n[i].max > max) { if(g_l(n[i], end)) push(q, lc(i), start, end); else if(g_r(n[i], start)) push(q, rc(i), start, end); else { push(q, lc(i), start, mid(i)); push(q, rc(i), mid(i) + 1, end); } } } } }; int main() { int n, m; line_tree* ptree = new line_tree(); line_tree& tree = *ptree; while(scanf("%d%d", &n, &m) != EOF) { // line_tree* ptree = new line_tree(); // line_tree& tree = *ptree; // tree.create(n); vector<int> values; for(int i = 0; i < n; i++) { int t; scanf("%d", &t); // tree.insert(i, t); values.push_back(t); } tree.insert(values); #ifdef __DEBUG tree.dump(0, n - 1); #endif for(int i = 0; i < m; i++) { int a, b; scanf("%d%d", &a, &b); int min, max; if(a == b) { min = max; } else if(b - a < 16) { min = values[a - 1]; max = values[a - 1]; for(int i = a; i < b; i++) { if(values[i] < min) min = values[i]; if(values[i] > max) max = values[i]; } } else tree.query(a - 1, b - 1, min, max); printf("%d\n", max - min); } // delete ptree; } delete ptree; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator