middle BZOJ2653

来源:互联网 发布:邮箱搜索软件 编辑:程序博客网 时间:2024/05/20 20:43

 我们平时建立函数式线段树的顺序都是按照索引建立,值作为线段树的区间,此题我们要按值的顺序建立,将索引作为线段树的区间,又涨姿势了...

具体可以参考爱神的题解: http://blog.csdn.net/acm_cxlove/article/details/8566093


#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <cstring>#include <stack>#include <cctype>#include <utility>   #include <map>#include <string>  #include <climits> #include <set>#include <string>    #include <sstream>#include <utility>   #include <ctime>#include <bitset>using std::priority_queue;using std::vector;using std::swap;using std::stack;using std::sort;using std::max;using std::min;using std::pair;using std::map;using std::string;using std::cin;using std::cout;using std::set;using std::queue;using std::string;using std::stringstream;using std::make_pair;using std::getline;using std::greater;using std::endl;using std::multimap;using std::deque;using std::unique;using std::lower_bound;using std::random_shuffle;using std::bitset;using std::upper_bound;using std::multiset;typedef long long LL;typedef unsigned long long ULL;typedef unsigned UN;typedef pair<int, int> PAIR;typedef multimap<int, int> MMAP;typedef LL TY;typedef long double LF;const int MAXN(500010);const int MAXM(50010);const int MAXE(150010);const int MAXK(6);const int HSIZE(13131);const int SIGMA_SIZE(4);const int MAXH(20);const int INFI((INT_MAX-1) >> 1);const ULL BASE(31);const LL LIM(1e13);const int INV(-10000);const int MOD(31313);const double EPS(1e-7);const LF PI(acos(-1.0));template<typename T> inline void checkmax(T &a, T b){if(b > a) a = b;}template<typename T> inline void checkmin(T &a, T b){if(b < a) a = b;}template<typename T> inline T ABS(const T &a){return a < 0? -a: a;}int ls[MAXN], rs[MAXN], sum[MAXN], lsum[MAXN], rsum[MAXN], root[20010], tab[20010];int rear;void push_up(int rt){sum[rt] = sum[ls[rt]]+sum[rs[rt]];lsum[rt] = max(lsum[ls[rt]], sum[ls[rt]]+lsum[rs[rt]]);rsum[rt] = max(rsum[rs[rt]], sum[rs[rt]]+rsum[ls[rt]]);}void build(int l, int r, int &rt){rt = rear++;if(l == r){sum[rt] = lsum[rt] = rsum[rt] = 1;return;}int m = (l+r) >> 1;build(l, m, ls[rt]);build(m+1, r, rs[rt]);push_up(rt);}void updata(int l, int r, int val, int prt, int &rt){rt = rear++;ls[rt] = ls[prt];rs[rt] = rs[prt];if(l == r){sum[rt] = lsum[rt] = rsum[rt] = -1;return;}int m = (l+r) >> 1;if(val <= m) updata(l, m, val, ls[prt], ls[rt]);else updata(m+1, r, val, rs[prt], rs[rt]);push_up(rt);}int query(int l, int r, int ql, int qr, int rt){if(ql <= l && qr >= r) return sum[rt];int m = (l+r) >> 1, ret = 0;if(ql <= m) ret = query(l, m, ql, qr, ls[rt]);if(qr > m) ret += query(m+1, r, ql, qr, rs[rt]);return ret;}int queryl(int l, int r, int ql, int qr, int rt){if(ql == l && qr == r) return lsum[rt];int m = (l+r) >> 1, ret;if(qr <= m) ret = queryl(l, m, ql, qr, ls[rt]);else if(ql > m) ret = queryl(m+1, r, ql, qr, rs[rt]);else ret = max(queryl(l, m, ql, m, ls[rt]), query(l, m, ql, m, ls[rt])+queryl(m+1, r, m+1, qr, rs[rt]));return ret;}int queryr(int l, int r, int ql, int qr, int rt){if(ql == l && qr == r) return rsum[rt];int m = (l+r) >> 1, ret;if(qr <= m) ret = queryr(l, m, ql, qr, ls[rt]);else if(ql > m) ret = queryr(m+1, r, ql, qr, rs[rt]);else ret = max(queryr(m+1, r, m+1, qr, rs[rt]), query(m+1, r, m+1, qr, rs[rt])+queryr(l, m, ql, m, ls[rt]));return ret;}int n;bool check(int val, int a, int b, int c, int d){int temp = queryr(0, n-1, a, b, root[val-1]);if(b+1 < c) temp += query(0, n-1, b+1, c-1, root[val-1]);temp += queryl(0, n-1, c, d, root[val-1]);return temp >= 0;}PAIR arr[20010];int q[4];int main(){while(~scanf("%d", &n)){for(int i = 0; i < n; ++i){scanf("%d", tab+i);arr[i] = PAIR(tab[i], i);}sort(tab, tab+n);int tn = unique(tab, tab+n)-tab;for(int i = 0; i < n; ++i) arr[i].first = lower_bound(tab, tab+tn, arr[i].first)-tab+1;sort(arr, arr+n);rear = 0;build(0, n-1, root[0]);updata(0, n-1, arr[0].second, root[0], root[arr[0].first]);for(int i = 1; i < n; ++i) updata(0, n-1, arr[i].second, root[arr[i-1].first], root[arr[i].first]);int Q, ans = 0;scanf("%d", &Q);while(Q--){scanf("%d%d%d%d", q, q+1, q+2, q+3);for(int i = 0; i < 4; ++i) q[i] = (q[i]+ans)%n;sort(q, q+4);int l = 1, r = tn+1;while(l < r){int m = (l+r) >> 1;if(check(m, q[0], q[1], q[2], q[3])) l = m+1;else r = m;}--l;ans = tab[l-1];printf("%d\n", ans);}}return 0;}