【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 }