zoukankan      html  css  js  c++  java
  • 【NOIP模拟赛】beautiful 乱搞(平衡树)+ST

    biubiu~~~

    我用平衡树处理的这道题,然而这种方法还是要看评测姬.....

    正解是乱搞....就是枚举每一位数作为中位数,比他小的看做-1比他大的看做1,那么我们从一开始就有了一个绵延的山,我们记录这个数之前出现过的距水平线高度差,如果我们在右边找到了这个同样的距离就意味着我们中间的操作为0那么在这两个相同水平面之前的距离就是他作为中位数的一个区间。

    似乎这是一种中位数套路........

    #include <cstdio>
    namespace Pre{
      inline void read(int &sum){
        register char ch=getchar();
        for(sum=0;ch<'0'||ch>'9';ch=getchar());
        for(;ch>='0'&&ch<='9';sum=(sum<<1)+(sum<<3)+ch-'0',ch=getchar());
      }
      inline int Max(int x,int y){
        return x>y?x:y;
      }
      int a[2017],n;
      int Ans[2017];
      int St[2017][15],LOG[2017],Bin[15];
      inline int get_ans(int l,int r){
        int len=r-l+1;
        return Max(St[l][LOG[len]],St[r-Bin[LOG[len]]+1][LOG[len]]);
      }
    }
    namespace Point{
      struct point{
        int key,pos;
        inline friend bool operator < (point a,point b);
        inline friend bool operator > (point a,point b);
      }A[2017];
      inline bool operator < (point a,point b){
        return a.key<b.key||(a.key==b.key&&a.pos<b.pos);
      }
      inline bool operator > (point a,point b){
        return b<a;
      }
    }
    namespace SGT{
      const double alpha=0.75;
      struct ScapeGoat_Tree{
        ScapeGoat_Tree *ch[2];
        int size;
        Point::point key;
        void pushup(){
          size=ch[0]->size+ch[1]->size+1;
        }
        bool isbad(){
          return size*alpha+5<ch[0]->size||size*alpha+5<ch[1]->size;
        }
      }*null,*root,mempool[4020],*stack[4020],*list[4020];
      int len,top;
      inline void Init(){
        null=mempool;
        null->ch[0]=null->ch[1]=null;
        root=null;
        for(int i=1;i<4020;i++)stack[++top]=mempool+i;
      }
      inline ScapeGoat_Tree *New(Point::point key){
        ScapeGoat_Tree *p=stack[top--];
        p->ch[0]=p->ch[1]=null;
        p->size=1;
        p->key=key;
        return p;
      }
      inline void clear(ScapeGoat_Tree *p){
        if(p==null)return;
        clear(p->ch[0]);
        clear(p->ch[1]);
        stack[++top]=p;
      }
      inline void Clear(){
        clear(root);
        root=null;
      }
      inline void travel(ScapeGoat_Tree *p){
        if(p==null)return;
        travel(p->ch[0]);
        list[++len]=p;
        travel(p->ch[1]);
      }
      inline ScapeGoat_Tree *divide(int l,int r){
        if(l>r)return null;
        int mid=(l+r)>>1;
        list[mid]->ch[0]=divide(l,mid-1);
        list[mid]->ch[1]=divide(mid+1,r);
        list[mid]->pushup();
        return list[mid];
      }
      inline void rebuild(ScapeGoat_Tree *&p){
        len=0;
        travel(p);
        p=divide(1,len);
      }
      inline ScapeGoat_Tree **insert(ScapeGoat_Tree *&p,Point::point key){
        if(p==null){
          p=New(key);
          return &null;
        }
        p->size++;
        ScapeGoat_Tree **ret=insert(p->ch[key>p->key],key);
        if(p->isbad())ret=&p;
        return ret;
      }
      inline void Insert(Point::point key){
        ScapeGoat_Tree **p=insert(root,key);
        if(*p!=null)rebuild(*p);
      }
      inline Point::point get_kth(int k){
        ScapeGoat_Tree *p=root;
        while(1)
          if(p->ch[0]->size>=k)p=p->ch[0];
          else if(p->ch[0]->size+1==k)return p->key;
          else k-=p->ch[0]->size+1,p=p->ch[1];
      }
    }
    namespace PRE_WORK{
      void Get_Max(){
        using namespace Point;
        for(int i=1;i<=Pre::n;i++){
          SGT::Clear();
          Pre::Ans[i]=Pre::Max(1,Pre::Ans[i]);
          SGT::Insert(A[i]);
          for(int j=i+1;j<=Pre::n;j++){
            SGT::Insert(A[j]);
            if(SGT::root->size&1){
              int Num=SGT::get_kth((SGT::root->size+1)>>1).pos;
              Pre::Ans[Num]=Pre::Max(Pre::Ans[Num],SGT::root->size);
            }
          }
        }
      }
      void Get_ST(){
        using namespace Pre;
        Bin[0]=1;
        for(int i=1;i<15;i++)Bin[i]=Bin[i-1]<<1;
        LOG[0]=-1;
        for(int i=1;i<=n;i++)LOG[i]=LOG[i>>1]+1;
        for(int i=1;i<=n;i++)St[i][0]=Ans[i];
        for(int i=1;Bin[i]<=n;i++)
          for(int j=1;j+Bin[i]-1<=n;j++)
            St[j][i]=Max(St[j][i-1],St[j+Bin[i-1]][i-1]);
      }
    }
    namespace Main{
      inline void Init(){
        SGT::Init();
        using Pre::read;
        read(Pre::n);
        for(int i=1;i<=Pre::n;i++){
          read(Pre::a[i]);
          Point::A[i]=(Point::point){Pre::a[i],i};
        }
        PRE_WORK::Get_Max();
        PRE_WORK::Get_ST();
      }
      inline void Work(){
        using namespace Pre;
        int Q;read(Q);
        for(int i=1,l,r;i<=Q;i++){
          read(l),read(r);
          printf("%d
    ",get_ans(l,r));
        }
      }
    }
    int main(){
      using namespace Main;
      Init(),Work();
      return 0;
    }
  • 相关阅读:
    Qt 学习 之 二进制文件读写
    QT学习 之 文本文件读写
    Qt学习 之 文件
    QT学习 之 三维饼图绘制
    Haskell 笔记(四)函数系统
    QT学习 之 事件与事件过滤器(分为五个层次)
    Qt学习 之 数据库(支持10种数据库)
    Qt5制作鼠标悬停显示Hint的ToolTip
    【码云周刊第 32 期】程序员眼中的 Vue 与 Angular !
    Qt学习 之 多线程程序设计(QT通过三种形式提供了对线程的支持)
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7327508.html
Copyright © 2011-2022 走看看