zoukankan      html  css  js  c++  java
  • 【BZOJ】【3489】A simple rmq problem

    KD-Tree(乱搞)


      Orz zyf教给蒟蒻做法

      蒟蒻并不会这题正解……(可持久化树套树?。。。Orz

      对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]),其中 i 满足$ ( pre[i]<ql and nex[i]>qr and i in [ql,qr] ) $

      然后我们以(i,pre[i],nex[i])为坐标……将所有点抽象到三维空间中,每次查询就相当于是一次区域求最值!

    这题我的感受:

    因为前面做了两道区域求和的……然后思路不由自主又代入到搞【子树最大值】来更新答案……然而忘记了单点更新,也就是:虽然这个子树不合法,但是这一个点(根)还是可能合法的……

    然后就是:KD-Tree如果可以搞整个子树的话,那么用整个子树的最值去更新,会优化很多……?

    终于1A了一道KD-Tree啦~好开心(虽然不是自己想出的做法……)

    一个更加优秀的做法:http://www.cnblogs.com/mhy12345/p/4517347.html

      1 /**************************************************************
      2     Problem: 3489
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:3712 ms
      7     Memory:7920 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 3489
     11 #include<cstdio>
     12 #include<cstring>
     13 #include<cstdlib>
     14 #include<iostream>
     15 #include<algorithm>
     16 #define rep(i,n) for(int i=0;i<n;++i)
     17 #define F(i,j,n) for(int i=j;i<=n;++i)
     18 #define D(i,j,n) for(int i=j;i>=n;--i)
     19 #define pb push_back
     20 using namespace std;
     21 typedef long long LL;
     22 inline int getint(){
     23     int r=1,v=0; char ch=getchar();
     24     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
     25     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
     26     return r*v;
     27 }
     28 const int N=100010,INF=1e9;
     29 /*******************template********************/
     30 int n,m,D,a[N],root,ans,now[N],nex[N],pre[N];
     31 struct node{
     32     int d[3],mn[3],mx[3],l,r,v,vmax;
     33     int& operator [] (int i) {return d[i];}
     34 }t[N];
     35 //d[0] 下标
     36 //d[1] nex
     37 //d[2] pre
     38 bool operator < (node a,node b){return a[D]<b[D];}
     39  
     40 #define L t[o].l
     41 #define R t[o].r
     42 #define mid (l+r>>1)
     43 void Push_up(int o){
     44     F(i,0,2){
     45         t[o].mn[i]=min(t[o][i],min(t[L].mn[i],t[R].mn[i]));
     46         t[o].mx[i]=max(t[o][i],max(t[L].mx[i],t[R].mx[i]));
     47     }
     48     t[o].vmax=max(t[o].v,max(t[L].vmax,t[R].vmax));
     49 }
     50  
     51 int build(int l,int r,int dir){
     52     D=dir;
     53     nth_element(t+l,t+mid,t+r+1);
     54     int o=mid;
     55     L = l < mid ? build(l,mid-1,(dir+1)%3) : 0;
     56     R = mid < r ? build(mid+1,r,(dir+1)%3) : 0;
     57     Push_up(o);
     58     return o;
     59 }
     60 int ql,qr;
     61 inline bool check(int o){
     62     if (!o) return 0;
     63     if (t[o].mx[1]<=qr || t[o].mn[2]>=ql) return 0;
     64     if (t[o].mn[0]>qr || t[o].mx[0]<ql) return 0;
     65     return 1;
     66 }
     67 void query(int o){
     68     if (!o) return;
     69     if (t[o].mn[0]>=ql && t[o].mx[0]<=qr && t[o].mn[1]>qr && t[o].mx[2]<ql){
     70         ans=max(ans,t[o].vmax);
     71         return;
     72     }
     73     if (t[o][0]>=ql && t[o][0]<=qr && t[o][1]>qr && t[o][2]<ql)
     74         ans=max(ans,t[o].v);
     75     if (t[L].vmax>t[R].vmax){
     76         if (t[L].vmax>ans && check(L)) query(L);
     77         if (t[R].vmax>ans && check(R)) query(R);
     78     }else{
     79         if (t[R].vmax>ans && check(R)) query(R);
     80         if (t[L].vmax>ans && check(L)) query(L);
     81     }
     82 }
     83 int main(){
     84 #ifndef ONLINE_JUDGE
     85     freopen("3489.in","r",stdin);
     86     freopen("3489.out","w",stdout);
     87 #endif
     88     F(i,0,2) t[0].mn[i]=INF,t[0].mx[i]=-INF;
     89     t[0].vmax=-1;
     90     n=getint(); m=getint();
     91     F(i,1,n) a[i]=getint();
     92     F(i,1,n){
     93         pre[i]=now[a[i]];
     94         now[a[i]]=i;
     95     }
     96     F(i,1,n) nex[pre[i]]=i;
     97     F(i,1,n) if (!nex[i]) nex[i]=n+1;
     98     F(i,1,n) t[i][0]=i,t[i][1]=nex[i],t[i][2]=pre[i],t[i].v=a[i];
     99     root=build(1,n,0);
    100     F(i,1,m){
    101         int x=getint(),y=getint();
    102         ql=min( (x+ans)%n+1,(y+ans)%n+1);
    103         qr=max( (x+ans)%n+1,(y+ans)%n+1);
    104         ans=0;
    105         query(root);
    106         printf("%d
    ",ans);
    107     }
    108     return 0;
    109 }
    View Code

    3489: A simple rmq problem

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 554  Solved: 173
    [Submit][Status][Discuss]

    Description

    因为是OJ上的题,就简单点好了。给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大。如果找不到这样的数,则直接输出0。我会采取一些措施强制在线。

     

     

    Input

    第一行为两个整数N,MM是询问数,N是序列的长度(N<=100000M<=200000)

    第二行为N个整数,描述这个序列{ai},其中所有1<=ai<=N

    再下面M行,每行两个整数xy

    询问区间[l,r]由下列规则产生(OIER都知道是怎样的吧>_<)

    l=min(x+lastans)mod n+1,(y+lastansmod n+1);

    r=max(x+lastans)mod n+1,(y+lastansmod n+1);

    Lastans表示上一个询问的答案,一开始lastans0

     

    Output

    一共M行,每行给出每个询问的答案。

     

    Sample Input

    10 10
    6 4 9 10 9 10 9 4 10 4
    3 8
    10 1
    3 4
    9 4
    8 1
    7 8
    2 9
    1 1
    7 3
    9 9

    Sample Output

    4
    10
    10
    0
    0
    10
    0
    4
    0
    4

    HINT



    注意出题人为了方便,input的第二行最后多了个空格。


     

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    美联储主席和欧洲央行说了什么
    12月CPI,PPI有哪些变化
    中国人民银行行长易纲就贯彻落实中央经济工作会议精神接受采访谈
    2018年个人的一些简单预测
    从首套房利率走势看市场
    百城价格房价周期和郑州、武汉房价比较分析
    国际非农超预期美联储主席态度软化,国内适度宽松货币+积极财政仍是主基调
    三大经济体年2018年末形势一览
    从房地产住宅销售面积增速看房地产行业
    枚举类
  • 原文地址:https://www.cnblogs.com/Tunix/p/4522925.html
Copyright © 2011-2022 走看看