• BZOJ2264 : Free Goodies


    如果Jan先手,那么可以放入一个对Petra来说价值$inf$的物品,就变成了Petra先手。

    对于Petra来说,拿物品的顺序是固定的,按这个顺序排序。

    那么如果把Petra的选择看成$($,Jan的选择看成$)$,一个合法的方案对应了一个合法括号序列。

    因此贪心选取$lfloorfrac{n}{2} floor$个价值最大的右括号,同时保证不破坏括号序列合法性即可,线段树维护。

    时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=1010,M=2050;
    int T,n,i,k,x,ansa,ansb,vs[M],vb[M],tag[M];char U[9];
    struct P{int a,b;}a[N];
    inline bool cmp(const P&a,const P&b){return a.a==b.a?a.b<b.b:a.a>b.a;}
    inline void add1(int x,int p){vs[x]+=p,tag[x]+=p;}
    inline void pb(int x){if(tag[x])add1(x<<1,tag[x]),add1(x<<1|1,tag[x]),tag[x]=0;}
    inline int merge(int x,int y){return a[x].b>a[y].b?x:y;}
    inline void up(int x){
      vs[x]=min(vs[x<<1],vs[x<<1|1]);
      vb[x]=merge(vb[x<<1],vb[x<<1|1]);
    }
    void build(int x,int a,int b){
      tag[x]=0;
      if(a==b){vs[x]=vb[x]=a;return;}
      int mid=(a+b)>>1;
      build(x<<1,a,mid),build(x<<1|1,mid+1,b),up(x);
    }
    void add(int x,int a,int b,int c){
      if(c<=a){add1(x,-2);return;}
      pb(x);
      int mid=(a+b)>>1;
      if(c<=mid)add(x<<1,a,mid,c);
      add(x<<1|1,mid+1,b,c);
      up(x);
    }
    void change(int x,int a,int b,int c){
      if(a==b){vb[x]=0;return;}
      pb(x);
      int mid=(a+b)>>1;
      if(c<=mid)change(x<<1,a,mid,c);else change(x<<1|1,mid+1,b,c);
      up(x);
    }
    int askmax(int x,int a,int b,int c){
      if(c<=a)return vb[x];
      pb(x);
      int mid=(a+b)>>1,t=0;
      if(c<=mid)t=askmax(x<<1,a,mid,c);
      t=merge(t,askmax(x<<1|1,mid+1,b,c));
      up(x);
      return t;
    }
    int right(int x,int a,int b){
      if(vs[x]>1)return 0;
      if(a==b)return a;
      pb(x);
      int mid=(a+b)>>1,t=right(x<<1|1,mid+1,b);
      if(!t)t=right(x<<1,a,mid);
      up(x);
      return t;
    }
    int main(){
      scanf("%d",&T);
      while(T--){
        scanf("%d%s",&n,U);
        for(i=1;i<=n;i++)scanf("%d%d",&a[i].a,&a[i].b),ansa+=a[i].a;
        if(U[0]=='J'){
          n++;
          a[n].a=1010;
          a[n].b=0;
        }
        sort(a+1,a+n+1,cmp);
        build(1,1,n);
        for(i=n/2;i;i--){
          k=right(1,1,n);
          x=askmax(1,1,n,k+1);
          ansa-=a[x].a;
          ansb+=a[x].b;
          change(1,1,n,x);
          add(1,1,n,x);
        }
        printf("%d %d
    ",ansa,ansb);
        ansa=ansb=0;
      }
      return 0;
    }
    

      

  • 相关阅读:
    [dev][ipsec][esp] ipsec链路中断的感知问题
    [dev] Go语言查看doc与生成API doc
    [daily]gtk程序不跟随系统的dark主题
    [dev] Go的协程切换问题
    基因程序设计/基因编程/遗传编程
    [daily][emacs][go] 配置emacs go-mode的编辑环境以及环境变量问题
    Java Spring中@Query中使用JPQL LIKE 写法
    JavaScript 使用HTML DOM的oninput事件,实时监听value值变化
    Java中执行.exe文件
    Java关于List<String> 进行排序,重写Comparator()方法
  • 原文地址:https://www.cnblogs.com/clrs97/p/6295044.html
Copyright © 2020-2023  润新知