• [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 }
    让本傻很是骄傲的系列
  • 相关阅读:
    uva 10066 The Twin Towers (最长公共子)
    warning: directory not found for option &#39; &#39;
    Hadoop-2.4.0安装和wordcount执行验证
    Android中的动画具体解释系列【1】——逐帧动画
    python学习1(小白记录)
    Struts2 开发环境搭建
    SlidingMenu开源项目滑动界面的实现总结
    ubuntu终端方向键不能用(主机名不显示)问题的解决
    Gnu Linux--Ubuntu系统清理项整理
    Task Schedule
  • 原文地址:https://www.cnblogs.com/dyllalala/p/3897855.html
Copyright © 2020-2023  润新知