[BZOJ 3489]A simple rmq problem

因为机房的网络管制实在是太厉(sang)害(bing)了

百度空间神马的根本不能上,就算上了也是慢的要死(你懂的)

于是,是时候体现博客园的强大了(作死)

祝我空降成功吧,喵~

这是我在 BZOJ 上 solve 的第 128 题, 不妨庆祝一下喵~

作为一个平时刷题看到什么做什么,懒得去挑题,又没有权限号来虐 bzoj 第 7 版的大傻叉来说,刷到 128 题还是真的很不容易……

正如那句真理: 题目做法和题目名字永远没有半毛钱关系

我们又很高兴的看到此题的做法果然——

和RMQ没有半毛钱关系

出题人在 noip 吧上曾说,std 是树套堆,又笑看大神一行树套 set 怒打出题人脸

可惜,像我这种傻 X ,既不会树套堆,又不会树套 set , 就只好请出傻 X 的专利 —— Straight Forward (又译 Brute Force)

令 next[i] 为 满足 j>ia[i]==a[j] 的最小的 j (如果没有则为 N+1)

令 last[i] 为 满足 i<ja[i]==a[j] 的最大的 i (如果没有则为 0)

则对于询问 [l..r] 明显我们要找的是 满足 l<=i<=r0<=last[i]<lr<next[i]<=N+1最大的 a[i]

额, 你问我怎么做?树套树套树就可以了, 然后……我写了个可持久化二维线段树

在 RE 和 MLE 中徘徊了许久后, 我居然跳过了 WA 和 TLE 直奔 AC 了!

而且只有 6816 MS O(∩_∩)O~ 果然我的线段树写法的常数还是很小的 有点小骄傲呢喵~

说指针慢的果然都是自己没写好喵~  @maoxiaohan1999

  1 #include <cstdio>
  2 #include <algorithm>
  3 const int size=100025;
  4 
  5 namespace IOspace
  6 {
  7     inline int getint()
  8     {
  9         register int num=0;
 10         register char ch;
 11         do ch=getchar(); while (ch<'0' || ch>'9');
 12         do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');
 13         return num;
 14     }
 15     inline void putint(int num, char ch='
')
 16     {
 17         char stack[15];
 18         register int top=0;
 19         if (num==0) stack[top=1]='0';
 20         for ( ;num;num/=10) stack[++top]=num%10+'0';
 21         for ( ;top;top--) putchar(stack[top]);
 22         if (ch) putchar(ch);
 23     }
 24 }
 25 
 26 struct item {int val, last, next;};
 27 
 28 int N, M;
 29 item a[size];
 30 int k[size];
 31 int last[size], next[size];
 32 inline int max(const int x, const int y) {return x>y?x:y;}
 33 inline void swap(int & x, int & y) {int t=x; x=y; y=t;}
 34 inline int cmp(int i, int j) {return a[i].last<a[j].last;}
 35 
 36 struct nodey {int val;        nodey * c[2];};
 37 struct nodex {nodey * val;    nodex * c[2];};
 38 nodex MEMx[2000000], * PORTx=MEMx;
 39 nodey MEMy[20000000], * PORTy=MEMy;
 40 nodex * seg[size];
 41 inline nodex * newnodex(nodex * x) {nodex * t=PORTx++; if (x) *t=*x; return t;}
 42 inline nodey * newnodey(nodey * y) {nodey * t=PORTy++; if (y) *t=*y; return t;}
 43 void inserty(nodey *& p, int l, int r, int k, int v)
 44 {
 45     int m=(l+r)>>1;
 46     p=newnodey(p);
 47     p->val=max(p->val, v);
 48     if (l==r) return ;
 49     if (k<=m) inserty(p->c[0], l, m, k, v);
 50     else inserty(p->c[1], m+1, r, k, v);
 51 }
 52 void insertx(nodex *& p, int l, int r, int x, int y, int v)
 53 {
 54     int m=(l+r)>>1;
 55     p=newnodex(p);
 56     inserty(p->val, 0, N+1, y, v);
 57     if (l==r) return ;
 58     if (x<=m) insertx(p->c[0], l, m, x, y, v);
 59     else insertx(p->c[1], m+1, r, x, y, v);
 60 }
 61 int queryy(nodey * y, int l, int r, int y1, int y2)
 62 {
 63     int m=(l+r)>>1;
 64     if (!y) return 0;
 65     if (l==y1 && r==y2) return y->val;
 66     if (y2<=m) return queryy(y->c[0], l, m, y1, y2);
 67     else if (y1>m) return queryy(y->c[1], m+1, r, y1, y2);
 68     return max(queryy(y->c[0], l, m, y1, m), queryy(y->c[1], m+1, r, m+1, y2));
 69 }
 70 int queryx(nodex * x, int l, int r, int x1, int x2, int y1, int y2)
 71 {
 72     int m=(l+r)>>1;
 73     if (!x) return 0;
 74     if (l==x1 && r==x2) return queryy(x->val, 0, N+1, y1, y2);
 75     if (x2<=m) return queryx(x->c[0], l, m, x1, x2, y1, y2);
 76     else if (x1>m) return queryx(x->c[1], m+1, r, x1, x2, y1, y2);
 77     return max(queryx(x->c[0], l, m ,x1, m, y1, y2), queryx(x->c[1], m+1, r, m+1, x2, y1, y2));
 78 }
 79 
 80 int main()
 81 {
 82     N=IOspace::getint(), M=IOspace::getint();
 83     for (int i=1;i<=N;i++) last[i]=0, next[i]=N+1;
 84     for (int i=1;i<=N;i++)
 85     {
 86         a[i].val=IOspace::getint();
 87         a[i].last=last[a[i].val];
 88         last[a[i].val]=i;
 89     }
 90     for (int i=N;i>=1;i--)
 91     {
 92         k[i]=i;
 93         a[i].next=next[a[i].val];
 94         next[a[i].val]=i;
 95     }
 96 
 97     std::sort(k+1, k+N+1, cmp);
 98 
 99     int j=1;
100     for (int i=0;i<N;i++)
101     {
102         if (i) seg[i]=seg[i-1];
103         for ( ;a[k[j]].last==i && j<=N;j++) insertx(seg[i], 0, N+1, a[k[j]].next, k[j], a[k[j]].val);
104     }
105 
106     int lastans=0;
107     for ( ;M;M--)
108     {
109         int l=IOspace::getint(), r=IOspace::getint();
110         l=(l+lastans)%N+1, r=(r+lastans)%N+1;
111         if (l>r) swap(l, r);
112         lastans=queryx(seg[l-1], 0, N+1, r+1, N+1, l, r);
113         IOspace::putint(lastans);
114     }
115 
116     return 0;
117 }
让本傻很是骄傲的系列
原文地址:https://www.cnblogs.com/dyllalala/p/3897855.html