zoukankan      html  css  js  c++  java
  • BZOJ4299 : Codechef FRBSUM

    若$[0,i]$的数都可以得到,那么$[1,所有不大于i+1的数的和]$的数都可以得到。

    如此暴力枚举答案,用可持久化线段树支持查询,因为每次数字至少翻一倍,所以复杂度为$O(mlog^2n)$。

    #include<cstdio>
    #include<algorithm>
    const int N=100010,M=1800000;
    int n,m,i,j,c,d,a[N],b[N],g[N],nxt[N],T[N],l[M],r[M],v[M],tot;
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline int lower(int x){
      int l=1,r=n,mid,t;
      while(l<=r)if(b[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
      return t;
    }
    int ins(int x,int a,int b,int c,int p){
      int y=++tot;v[y]=v[x]+p;
      if(a==b)return y;
      int mid=(a+b)>>1;
      if(c<=mid)l[y]=ins(l[x],a,mid,c,p),r[y]=r[x];else l[y]=l[x],r[y]=ins(r[x],mid+1,b,c,p);
      return y;
    }
    int ask(int x,int a,int b){
      if(!x)return 0;
      if(c<=a&&b<=d)return v[x];
      int mid=(a+b)>>1,t=0;
      if(c<=mid)t=ask(l[x],a,mid);
      if(d>mid)t+=ask(r[x],mid+1,b);
      return t;
    }
    inline int query(){for(i=0;;i=j)if((j=ask(T[lower(i+1)],1,n))==i)return i+1;}
    int main(){
      for(read(n),i=1;i<=n;i++)read(a[i]),b[i]=a[i];
      for(std::sort(b+1,b+n+1),i=1;i<=n;i++)nxt[i]=g[a[i]=lower(a[i])],g[a[i]]=i;
      for(i=1;i<=n;i++)for(T[i]=T[i-1],j=g[i];j;j=nxt[j])T[i]=ins(T[i],1,n,j,b[i]);
      for(read(m);m--;printf("%d
    ",query()))read(c),read(d);
      return 0;
    }
    

      

  • 相关阅读:
    caioj 1914 & CH 0x20搜索(0x27A*)例题1:第K短路 Remmarguts'Date
    多项式的化简求法
    caioj 1715 表达式的转换
    HDU 2829 Lawrence
    山海经 (线段树)
    神奇的KMP
    浅谈zkw线段树(by Shine_hale)
    线段树补充
    浅谈线段树(by Shine_hale)
    k短路
  • 原文地址:https://www.cnblogs.com/clrs97/p/4873167.html
Copyright © 2011-2022 走看看