【BZOJ3489】A simple rmq problem(树套树)

链接w:http://www.lydsy.com/JudgeOnline/problem.php?id=3489

题解:http://blog.csdn.net/PoPoQQQ/article/details/42104273

QwQ树套树好容易T啊,于是在磊少的带领下爽卡一波常数~

 

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <iostream>
  4 #include <algorithm>
  5 #define MaxN 100010
  6 #define MaxM 40000010
  7 using namespace std;
  8 int S = 0, n, m, N, tot = 0, ret = 0;
  9 int pre[MaxN], suf[MaxN], root[MaxN];
 10 int ls[MaxM], rs[MaxM], Max[MaxM];
 11 struct tree{
 12     int ls, rs, root;
 13 }tr[MaxN*20];
 14 struct rec{
 15     int pre, suf, v, id;
 16 }num[MaxN];
 17 namespace IStream {
 18     const int L = 1 << 15;
 19     char buffer[L], *S, *T;
 20     inline char Get_Char() {
 21         if(S == T) {
 22             T = (S = buffer) + fread(buffer, 1, L, stdin);
 23             if(S == T) return EOF;
 24         }
 25         return *S++;
 26     }
 27     inline int Get_Int() {
 28         char c;
 29         int re = 0;
 30         for(c = Get_Char(); c < '0' || c > '9'; c = Get_Char());
 31         while(c >= '0' && c <= '9')
 32             re = (re << 1) + (re << 3) + (c - '0'), c = Get_Char();
 33         return re;
 34     }
 35 }
 36 
 37 bool cmp(rec a, rec b){
 38     return a.pre < b.pre;
 39 }
 40 
 41 inline void updata(int &x, int l, int r, int k, int v){
 42     int fa = x; x = ++tot;
 43     ls[x] = ls[fa], rs[x] = rs[fa];
 44     Max[x] = max(Max[fa], v);
 45     if (l == r) return;
 46     int mid = (l+r)>>1;
 47     if (k <= mid) updata(ls[x], l, mid, k, v);
 48     else updata(rs[x], mid+1, r, k, v);    
 49 }
 50 
 51 inline void updata(int &x, int l, int r, int pos, int k, int v){
 52     int fa = x; x = ++S;
 53     tr[x] = tr[fa];
 54     updata(tr[x].root, 1, n, k, v);
 55     if (l == r) return;
 56     int mid = (l+r)>>1;
 57     if (pos <= mid) updata(tr[x].ls, l, mid, pos, k, v);
 58     else updata(tr[x].rs, mid+1, r, pos, k, v);
 59 }
 60 
 61 inline void query(int x, int l, int r, int a, int b){
 62     if (!x) return;
 63     if (a <= l && b >= r) {
 64         ret = max(ret, Max[x]);
 65         return ;
 66     }
 67     int mid = (l+r)>>1;
 68     if (a <= mid) query(ls[x], l, mid, a, b);
 69     if (b > mid) query(rs[x], mid+1, r, a, b);
 70 }
 71 
 72 inline void query(int x, int l, int r, int a, int b, int L, int R){
 73     if (a <= l && b >= r) {
 74         query(tr[x].root, 1, n, L, R);
 75         return;
 76     }
 77     int mid = (l+r)>>1;
 78     if (a <= mid) query(tr[x].ls, l, mid, a, b, L, R);
 79     if (b > mid) query(tr[x].rs, mid+1, r, a, b, L, R);
 80 }
 81 
 82 inline void Read_Data(){
 83     n = IStream::Get_Int(); m = IStream::Get_Int(); N = n+1;
 84     for (int i = 1; i <= n; i++) num[i].v = IStream::Get_Int(), pre[i] = 0, suf[i] = n+1, num[i].id = i;
 85     for (int i = 1; i <= n; i++) num[i].pre = pre[num[i].v], pre[num[i].v] = i;
 86     for (int i = n; i > 0; i--) num[i].suf = suf[num[i].v], suf[num[i].v] = i;
 87     sort(num+1, num+1+n, cmp);
 88     for (int i = 0, j = 1; i < n; i++){
 89         if (i) root[i] = root[i-1];
 90         while(j <= n && num[j].pre == i){
 91             updata(root[i], 0, N, num[j].suf, num[j].id, num[j].v);
 92             j++;
 93         }
 94     }
 95 }
 96 
 97 inline void Solve(){
 98     int l, r, ans = 0;
 99     for (int i = 1; i <= m; i++){
100         l = IStream::Get_Int(); r = IStream::Get_Int();
101         l = (l+ans)%n+1; r = (r+ans)%n+1;
102         if (l > r) swap(l, r);
103         query(root[l-1], 0, N, r+1, N, l, r);
104         ans = ret; ret = 0;
105         printf("%d\n", ans);
106     }
107 }
108 
109 int main(){
110     freopen("bzoj3489.in", "r", stdin);
111     freopen("bzoj3489.out", "w", stdout);
112     Read_Data();
113     Solve();
114     return 0;    
115 }

 

posted @ 2016-03-14 10:17  Lukaluka  阅读(299)  评论(0编辑  收藏  举报