poj 3977 Subset 枚举+二分

2014-11-24 13:06:07 · 作者: · 浏览: 1

首先分成一半2^17和2^18,并且把其中一半变成相反数,然后枚举一半二分查找另一半,在找到的位置前后也找找。

这里用到了二级排序,有很多细节要处理,不多说了。

巨坑的一个地方就是,不能用系统的abs,要自己手写,简直坑死。。



#include
  
   
#include
   
     #include
    
      #include
      using namespace std; typedef long long ll; struct node { int num; ll val; bool operator <(const node &x) const { if(val==x.val) return num
      
       n1) { if(num){ a[top1].val=sum; a[top1++].num=num; } return; } dfs1(now+1,sum+s[now],num+1); dfs1(now+1,sum,num); } void dfs2(int now,ll sum,int num) { if(now>n) { if(num){ b[top2].val=-sum; b[top2++].num=num; } return; } dfs2(now+1,sum+s[now],num+1); dfs2(now+1,sum,num); } ll myabs(ll a) { return a<0 -a:a; } int myabs(int a) { return a<0 -a:a; } void cal(int p) { node cq; cq.val=a[p].val; cq.num=0; int tmp=lower_bound(b,b+top2,cq)-b; ll tzf=myabs(a[p].val-b[tmp].val); if(tzf
       
        =0) { tzf=myabs(a[p].val-b[tmp-1].val); if(tzf