zoukankan      html  css  js  c++  java
  • BZOJ4358 : permu

    把询问看成二维点,建立kd-tree,每个点维护一个计数器。

    从1到n依次加入每个数,每次加入一个数时,对于所有包含它的询问,计数器加一,对于其它询问,计数器置0。

    那么每个询问的答案就是计数器的历史最大值,可以通过打标记实现。

    时间复杂度$O(nsqrt{m})$。

    #include<cstdio>
    #include<algorithm>
    const int N=50010,inf=-1,BUF=2000000;
    int n,m,i,x,id[N],root,cmp_d,X,a[N];char Buf[BUF],*buf=Buf;
    inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
    struct node{
      int D[2],l,r,Max[2],Min[2];
      int m,d,e,hm,hd,he;
    }t[N];
    inline bool cmp(const node&a,const node&b){return a.D[cmp_d]<b.D[cmp_d];}
    inline void Max(int&a,int b){if(a<b)a=b;}
    inline void Min(int&a,int b){if(a>b)a=b;}
    inline void up(int x){
      id[t[x].e]=x,t[x].e=t[x].he=inf;
      if(t[x].l){
        Max(t[x].Max[0],t[t[x].l].Max[0]);
        Min(t[x].Min[0],t[t[x].l].Min[0]);
        Max(t[x].Max[1],t[t[x].l].Max[1]);
        Min(t[x].Min[1],t[t[x].l].Min[1]);
      }
      if(t[x].r){
        Max(t[x].Max[0],t[t[x].r].Max[0]);
        Min(t[x].Min[0],t[t[x].r].Min[0]);
        Max(t[x].Max[1],t[t[x].r].Max[1]);
        Min(t[x].Min[1],t[t[x].r].Min[1]);
      }
    }
    int build(int l,int r,int D){
      int mid=(l+r)>>1;
      cmp_d=D,std::nth_element(t+l+1,t+mid+1,t+r+1,cmp);
      t[mid].Max[0]=t[mid].Min[0]=t[mid].D[0];
      t[mid].Max[1]=t[mid].Min[1]=t[mid].D[1];
      if(l!=mid)t[mid].l=build(l,mid-1,!D);
      if(r!=mid)t[mid].r=build(mid+1,r,!D);
      return up(mid),mid;
    }
    inline void hdoa(node&x,int v){
      Max(x.hm,x.m+v);
      if(x.e>inf)Max(x.he,x.e+v);else Max(x.hd,x.d+v);
    }
    inline void hdoc(node&x,int v){Max(x.hm,v);Max(x.he,v);}
    inline void doa(node&x,int v){
      Max(x.hm,x.m+=v);
      if(x.e>inf)Max(x.he,x.e+=v);else Max(x.hd,x.d+=v);
    }
    inline void doc(node&x,int v){Max(x.hm,x.m=v);Max(x.he,x.e=v);x.d=0;}
    inline void pb(node&x){
      if(x.hd){
        if(x.l)hdoa(t[x.l],x.hd);
        if(x.r)hdoa(t[x.r],x.hd);x.hd=0;
      }
      if(x.he>inf){
        if(x.l)hdoc(t[x.l],x.he);
        if(x.r)hdoc(t[x.r],x.he);
        x.he=inf;
      }
      if(x.d){
        if(x.l)doa(t[x.l],x.d);
        if(x.r)doa(t[x.r],x.d);
        x.d=0;
      }else if(x.e>inf){
        if(x.l)doc(t[x.l],x.e);
        if(x.r)doc(t[x.r],x.e);
        x.e=inf;
      }
    }
    void change(node&x){
      if(x.Min[0]>X||x.Max[1]<X){doc(x,0);return;}
      if(x.Max[0]<=X&&x.Min[1]>=X){doa(x,1);return;}
      pb(x);
      if(x.D[0]<=X&&x.D[1]>=X)Max(x.hm,++x.m);else x.m=0;
      if(x.l)change(t[x.l]);
      if(x.r)change(t[x.r]);
    }
    void dfs(node&x){
      pb(x);
      if(x.l)dfs(t[x.l]);
      if(x.r)dfs(t[x.r]);
    }
    int main(){
      fread(Buf,1,BUF,stdin),read(n),read(m);
      for(i=1;i<=n;i++)read(X),a[X]=i;
      for(i=1;i<=m;i++)read(t[i].D[0]),read(t[i].D[1]),t[i].e=i;
      root=build(1,m,1);
      for(i=1;i<=n;i++)X=a[i],change(t[root]);
      dfs(t[root]);
      for(i=1;i<=m;i++)printf("%d
    ",t[id[i]].hm);
      return 0;
    }
    

      

  • 相关阅读:
    [java学习点滴]PropertiesUtil 读取properties配置帮助类
    Java快速向数据库中插入大量数据 比如10万条以上
    Java通过IO流输入输出 向文件中存入大量三个属性的值,并通过验证前两个属性输出第三个属性
    JSON 的使用方法
    jQuery easyUI id选择器 类选择器 标签选择器 属性选择器 及DOM对象和jQuery相互之间的转换
    解决request中文乱码问题
    jsp内置对象request使用方法2
    jsp内置对象request的使用方法
    easyui-dialog对话框练习
    使用combobox下拉列表框实现省 市 县 的三级联动
  • 原文地址:https://www.cnblogs.com/clrs97/p/5049090.html
Copyright © 2011-2022 走看看