题意:有n个人,60种技能点,如果第i个人会第j种技能a[i]的二进制表示的第j位就是1,第i个人的价值是b[i]
如果有若干种技能i会j不会,i就会鄙视j
求一种至少两个人的选人方案使得价值和最大,而且不存在一个人鄙视剩余所有人
n<=7000,1<=b[i]<=1e9
思路:显然如果有n个人,他们的技能树完全一致,且n>=2,这些人肯定全取,用map维护一下
取完之后考虑剩下的,如果剩余的之间不存在超集关系他们必定互相鄙视
贪心,能加就加
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 typedef pair<ll,int>P; 11 #define N 200010 12 #define M 200010 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pi acos(-1) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 20 #define lowbit(x) x&(-x) 21 #define Rand (rand()*(1<<16)+rand()) 22 #define id(x) ((x)<=B?(x):m-n/(x)+1) 23 #define ls p<<1 24 #define rs p<<1|1 25 26 const ll MOD=1e9+7,inv2=(MOD+1)/2; 27 double eps=1e-4; 28 int INF=1<<30; 29 ll inf=5e13; 30 int dx[4]={-1,1,0,0}; 31 int dy[4]={0,0,-1,1}; 32 33 ll a[N],x1[N],x2[N]; 34 int b[N],y1[N],y2[N]; 35 map<ll,int> mp1; 36 map<ll,ll> mp2; 37 38 int read() 39 { 40 int v=0,f=1; 41 char c=getchar(); 42 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 43 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 44 return v*f; 45 } 46 47 int main() 48 { 49 mp1.clear(); 50 mp2.clear(); 51 int n=read(); 52 rep(i,1,n) scanf("%lld",&a[i]); 53 rep(i,1,n) b[i]=read(); 54 rep(i,1,n) 55 { 56 mp1[a[i]]++; 57 mp2[a[i]]+=b[i]; 58 } 59 ll ans=0,S=0; 60 int m=0; 61 rep(i,1,n) 62 if(mp1[a[i]]>=2) 63 { 64 ans+=mp2[a[i]]; 65 mp1[a[i]]=0; 66 x1[++m]=a[i]; 67 } 68 //printf("ans=%lld ",ans); 69 rep(i,1,n) 70 if(mp1[a[i]]) 71 { 72 int flag=0; 73 rep(j,1,m) 74 { 75 ll t1=a[i]^x1[j],t2=a[i]|x1[j]; 76 if(t1&&t2!=x1[j]) continue; 77 flag=1; break; 78 } 79 if(flag) 80 { 81 ans+=b[i]; 82 m++; 83 x1[m]=a[i]; 84 } 85 } 86 87 printf("%lld ",ans); 88 return 0; 89 }