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;
    }
    

      

  • 相关阅读:
    document
    winform(公共控件)
    winform属性
    ADO.NET(查询、属性扩展)
    ADO.NET(完整修改和查询、实体类,数据访问类)
    ADO.NET基础(增删改查)
    面向对象(类库、委托)
    c#复习整理
    面向对象(多态)
    面向对象(封装、继承)
  • 原文地址:https://www.cnblogs.com/clrs97/p/4873167.html
Copyright © 2011-2022 走看看