• BZOJ2872 : 优莱卡


    $A$类数据:直接输出$B[l]$,$O(n+m)$。
    $B$类数据:ST表求区间最小值,$O(nlog n+m)$。
    $C$类数据:可持久线段树求区间$k$小值,$O((n+m)log n)$。
    剩下的数据先用可持久线段树求出$a,b$的实际值,转化为矩形内$B$值的询问。
    $D$类数据:即求矩形$B$最小值,对序列分治,对于序列$[l,r]$,用扫描线+线段树处理所有经过$mid$的询问,$O(nlog^2n+mlog n)$。
    $E,F$类数据:即求矩形$B$第$k$小值,可持久化线段树套权值线段树即可,$O((n+m)log^2n)$。

    #include<cstdio>
    const int N=30010,M=N*18,BUF=30000000,OUT=10000000;
    char Buf[BUF],*buf=Buf,Out[OUT],*ou=Out;int Outn[30],Outcnt;
    inline void write(int x){
      if(!x)*ou++=48;
      else{
        for(Outcnt=0;x;x/=10)Outn[++Outcnt]=x%10+48;
        while(Outcnt)*ou++=Outn[Outcnt--];
      }
    }
    inline void writeln(int x){write(x);*ou++='
    ';}
    inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
    inline int readstr(char*a){
      int n=0;
      while(*buf<33)buf++;while(*buf>32)*a++=*buf++,n++;
      return n;
    }
    int n,m,e,i,j,l,r,c,d,k,a[N],b[N],last,v[M],sl[M],sr[M],tot,T[N];char type[9];
    namespace SubA{
    void Main(){
      while(m--)read(l),read(r),read(c),read(d),read(k),writeln(b[l]);
    }
    }
    int ins(int x,int a,int b,int c){
      int y=++tot;
      v[y]=v[x]+1;
      if(a==b)return y;
      int mid=(a+b)>>1;
      if(c<=mid)sl[y]=ins(sl[x],a,mid,c),sr[y]=sr[x];
      else sl[y]=sl[x],sr[y]=ins(sr[x],mid+1,b,c);
      return y;
    }
    int kth(int x,int y,int k){
      int a=1,b=n,mid,t;
      while(a<b){
        mid=(a+b)>>1;
        t=v[sl[x]]-v[sl[y]];
        if(k<=t)b=mid,x=sl[x],y=sl[y];else k-=t,a=mid+1,x=sr[x],y=sr[y];
      }
      return a;
    }
    namespace SubB{
    int Log[N],f[20][N];
    inline int min(int a,int b){return a<b?a:b;}
    inline int ask(int l,int r){
      int k=Log[r-l+1];
      return min(f[k][l],f[k][r-(1<<k)+1]);
    }
    void Main(){
      for(i=2;i<=n;i++)Log[i]=Log[i>>1]+1;
      for(i=1;i<=n;i++)f[0][i]=a[i];
      for(j=1;j<=Log[n];j++)for(i=1;i+(1<<j)-1<=n;i++)f[j][i]=min(f[j-1][i],f[j-1][i+(1<<(j-1))]);
      while(m--){
        read(l),read(r),read(c),read(d),read(k);
        writeln(ask(l,r));
      }
    }
    }
    namespace SubC{
    void Main(){
      while(m--){
        read(l),read(r),read(c),read(d),read(k);
        writeln(kth(T[r],T[l-1],c));
      }
    }
    }
    namespace SubD{
    const int MAXQ=500010;
    struct E{int l,r,a,b,ans;}q[MAXQ];
    int pool[N],cnt[N],v[MAXQ<<1],val[70000],M;
    inline void up(int&a,int b){a>b?(a=b):0;}
    inline int ask(int x,int y){
      int t=N;
      for(x+=M-1,y+=M+1;x^y^1;x>>=1,y>>=1){
        if(~x&1)up(t,val[x^1]);
        if(y&1)up(t,val[y^1]);
      }
      return t;
    }
    inline void change(int x,int y){for(x+=M;x;x>>=1)up(val[x],y);}
    inline void clear(int x){for(x+=M;x;x>>=1)val[x]=N;}
    void build(int n){
      for(M=1;M<n+2;M<<=1);
      int i;
      for(i=1;i<=n;i++)v[i+M]=a[i];
      for(i=M-1;i;i--)v[i]=v[i<<1]+v[i<<1|1];
    }
    void solve(int l,int r){
      if(l>r)return;
      int i,j,k,mid=(l+r)>>1;
      solve(l,mid-1),solve(mid+1,r);
      for(i=mid;i>=l;i--){
        change(a[i],b[i]);
        for(j=cnt[i];j>cnt[i-1];j--){
          k=v[j];
          if(q[k].l<=mid&&q[k].r>=mid&&q[k].l>=l&&q[k].r<=r)up(q[k].ans,ask(q[k].a,q[k].b));
        }
      }
      for(i=mid;i>=l;i--)clear(a[i]);
      for(i=mid;i<=r;i++){
        change(a[i],b[i]);
        for(j=cnt[i];j>cnt[i-1];j--){
          k=v[j];
          if(q[k].l<=mid&&q[k].r>=mid&&q[k].l>=l&&q[k].r<=r)up(q[k].ans,ask(q[k].a,q[k].b));
        }
      }
      for(i=mid;i<=r;i++)clear(a[i]);
    }
    void Main(){
      for(i=1;i<=m;i++){
        read(l),read(r),read(c),read(d),read(k);
        c=kth(T[r],T[l-1],c);
        d=kth(T[r],T[l-1],d);
        q[i].l=l,q[i].r=r,q[i].a=c,q[i].b=d,q[i].ans=N;
        cnt[l]++,cnt[r]++;
      }
      for(i=1;i<=n;i++)cnt[i]+=cnt[i-1];
      for(i=1;i<=n;i++)pool[i]=cnt[i];
      for(i=1;i<=m;i++)v[pool[q[i].l]--]=i,v[pool[q[i].r]--]=i;
      for(M=1;M<n+2;M<<=1);
      for(i=1;i<=n+M;i++)val[i]=N;
      solve(1,n);
      for(i=1;i<=m;i++)writeln(q[i].ans);
    }
    }
    namespace SubF{
    const int MAXN=9720000;
    int sonl[M],sonr[M],id[M],root[N],tot;
    int L[MAXN],R[MAXN],V[MAXN],TOT;
    int q[N][2],cnt;
    int INS(int x,int a,int b,int c){
      int y=++TOT;
      V[y]=V[x]+1;
      if(a==b)return y;
      int mid=(a+b)>>1;
      if(c<=mid)L[y]=INS(L[x],a,mid,c),R[y]=R[x];else L[y]=L[x],R[y]=INS(R[x],mid+1,b,c);
      return y;
    }
    int ins(int x,int a,int b,int c,int d){
      int y=++tot;
      id[y]=INS(id[x],0,n,d);
      if(a==b)return y;
      int mid=(a+b)>>1;
      if(c<=mid)sonl[y]=ins(sonl[x],a,mid,c,d),sonr[y]=sonr[x];
      else sonl[y]=sonl[x],sonr[y]=ins(sonr[x],mid+1,b,c,d);
      return y;
    }
    void ask(int x,int y,int a,int b,int c,int d){
      if(c<=a&&b<=d){
        q[++cnt][0]=id[x];
        q[cnt][1]=id[y];
        return;
      }
      int mid=(a+b)>>1;
      if(c<=mid)ask(sonl[x],sonl[y],a,mid,c,d);
      if(d>mid)ask(sonr[x],sonr[y],mid+1,b,c,d);
    }
    inline int query(int x,int y,int l,int r,int k){
      cnt=0;
      ask(x,y,1,n,l,r);
      int a=0,b=n,mid,t,i;
      while(a<b){
        mid=(a+b)>>1;
        t=0;
        for(i=1;i<=cnt;i++)t+=V[L[q[i][0]]]-V[L[q[i][1]]];
        if(k<=t){
          b=mid;
          for(i=1;i<=cnt;i++)q[i][0]=L[q[i][0]],q[i][1]=L[q[i][1]];
        }else{
          k-=t,a=mid+1;
          for(i=1;i<=cnt;i++)q[i][0]=R[q[i][0]],q[i][1]=R[q[i][1]];
        }
      }
      return a;
    }
    void Main(){
      for(i=1;i<=n;i++)root[i]=ins(root[i-1],1,n,a[i],b[i]);
      while(m--){
        read(l),read(r),read(c),read(d),read(k);
        k=(k-1+e*last)%(d-c+1)+1;
        c=kth(T[r],T[l-1],c);
        d=kth(T[r],T[l-1],d);
        last=query(root[r],root[l-1],c,d,k);
        writeln(last);
      }
    }
    }
    int main(){
      fread(Buf,1,BUF,stdin);
      readstr(type);
      read(n);
      for(i=1;i<=n;i++)read(a[i]);
      for(i=1;i<=n;i++)read(b[i]);
      read(m),read(e);
      if(type[0]=='A')SubA::Main();
      else if(type[0]=='B')SubB::Main();
      else{
        for(i=1;i<=n;i++)T[i]=ins(T[i-1],1,n,a[i]);
        if(type[0]=='C')SubC::Main();
        else if(type[0]=='D')SubD::Main();
        else SubF::Main();
      }
      fwrite(Out,1,ou-Out,stdout);
      return 0;
    }
    

      

  • 相关阅读:
    C# 泛型约束 xxx<T> Where T:约束(一)
    [cb]UIGrid+UIStretch的自适应
    UIButton vs UIEventListener 事件处理
    NGUI Clip Animation (UI动画)
    TexturePacker的plist切成单独小图片
    Collider Collision 区别
    It’s Time To Think Linq
    [cb]NGUI事件及复杂UI管理
    Unity Mono
    【android】getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()区别详解
  • 原文地址:https://www.cnblogs.com/clrs97/p/8456162.html
Copyright © 2020-2023  润新知