• BZOJ3022 : [Balkan2012]The Best Teams


    将选手和询问按照年龄排序,即可去掉年龄的限制。

    将所有选手按水平排序后维护线段树,显然最优解一定是从大到小贪心选择。

    线段树上每个节点维护:

    $g[0/1]:r+1$不选/选的时候,$l$选不选。

    $c[0/1]:r+1$不选/选的时候,中间选了几个。

    $s[0/1]:r+1$不选/选的时候,中间选的和。

    然后查询的时候在线段树上二分即可。

    时间复杂度$O((n+m)log n)$。

    #include<cstdio>
    #include<algorithm>
    #define N 300010
    typedef long long ll;
    int n,m,i,j,c[N],pos[N];ll ans[N];
    struct P{int x,y,p;}a[N],b[N];
    struct T{bool g[2];int c[2];ll s[2];}v[1050000];
    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 bool cmp(const P&a,const P&b){return a.x<b.x;}
    inline int lower(int x){
      int l=1,r=n,mid,t;
      while(l<=r)if(c[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
      return t;
    }
    void build(int x,int a,int b){
      if(a==b){pos[a]=x;return;}
      int mid=(a+b)>>1;
      build(x<<1,a,mid),build(x<<1|1,mid+1,b);
    }
    inline void change(int x,int y){
      x=pos[x];
      v[x].g[0]=v[x].c[0]=1,v[x].s[0]=y;
      for(x>>=1;x;x>>=1)for(int i=0;i<2;i++){
        bool j=v[x<<1|1].g[i];
        v[x].g[i]=v[x<<1].g[j];
        v[x].c[i]=v[x<<1|1].c[i]+v[x<<1].c[j];
        v[x].s[i]=v[x<<1|1].s[i]+v[x<<1].s[j];
      }
    }
    inline ll ask(int k){
      int x=1,a=1,b=n,mid,o=0;ll ret=0;
      while(k){
        if(k>=v[x].c[o]){ret+=v[x].s[o];break;}
        if(a==b)break;
        mid=(a+b)>>1;
        x=x<<1|1;
        if(k<=v[x].c[o])a=mid+1;
        else{
          k-=v[x].c[o];
          ret+=v[x].s[o];
          o=v[x].g[o];
          b=mid;
          x--;
        }
      }
      return ret;
    }
    int main(){
      read(n);
      for(i=1;i<=n;i++)read(a[i].x),read(a[i].y),c[i]=a[i].y;
      read(m);
      for(i=1;i<=m;i++)read(b[i].x),read(b[i].y),b[i].p=i;
      std::sort(a+1,a+n+1,cmp);
      std::sort(b+1,b+m+1,cmp);
      std::sort(c+1,c+n+1);
      build(1,1,n);
      for(i=j=1;i<=m;i++){
        while(j<=n&&a[j].x<=b[i].x)change(lower(a[j].y),a[j].y),j++;
        ans[b[i].p]=ask(b[i].y);
      }
      for(i=1;i<=m;i++)printf("%lld
    ",ans[i]);
      return 0;
    }
    

      

  • 相关阅读:
    HTML颜色表
    grid
    DOM和BO
    注册表
    js 正则表达式
    python学习之路(一)
    python学习之路(三)
    python学习之路(二)
    自己编写的泛型集合类(其实是照着微软的List写的)
    客户端回调服务端无刷新事件
  • 原文地址:https://www.cnblogs.com/clrs97/p/6382845.html
Copyright © 2020-2023  润新知