1315 合法整数集
思路:集合Y中两类数存在是不可能合成X的,一类是比X大的数,一类是X的二进制表示中某些位为0,而这些数对应的二进制表示的位的数字是1。先把这两类数字排除掉,
再对处理后的集合Y中的所有数字进行分位统计,最后那个X的二进制表示中为1的位中数字最小的就是答案了。
1 #include <iostream> 2 #include <queue> 3 #include <stack> 4 #include <cstdio> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <algorithm> 10 #include <cmath> 11 #include <cstring> 12 #include <cstdlib> 13 #include <string> 14 #include <sstream> 15 #include <time.h> 16 #define x first 17 #define y second 18 #define pb push_back 19 #define mp make_pair 20 #define lson l,m,rt*2 21 #define rson m+1,r,rt*2+1 22 #define mt(A,B) memset(A,B,sizeof(A)) 23 #define mod 1000000007 24 using namespace std; 25 typedef long long LL; 26 const double PI = acos(-1); 27 const int N=2e5+10; 28 const int inf = 0x3f3f3f3f; 29 const LL INF=0x3f3f3f3f3f3f3f3fLL; 30 LL x[100]; 31 int vis[100],ans=inf; 32 vector<LL> P,Q; 33 int main() 34 { 35 #ifdef Local 36 freopen("data.txt","r",stdin); 37 #endif 38 LL n,k,sum=0; 39 int flg=0; 40 cin>>n>>k; 41 mt(vis,0); 42 for(int i=0;i<n;i++)cin>>x[i]; 43 for(LL i=0;i<34;i++) 44 { 45 if(pow(2,i)>k)break; 46 else 47 { 48 49 if((LL)(k&(LL)pow(2,i))==0) 50 { 51 P.pb(i); 52 //printf("%lld %lld\n",i,pow(2,i)); 53 } 54 55 } 56 } 57 for(int i=0;i<n;i++) 58 { 59 int flag=0; 60 if(x[i]>k)continue; 61 for(int j=0;j<P.size();j++) 62 { 63 if(x[i]&(LL)pow(2,P[j])) 64 { 65 flag=1;break; 66 } 67 } 68 if(!flag)Q.pb(x[i]); 69 } 70 //for(int i=0;i<Q.size();i++)cout<<Q[i]<<endl; 71 for(int i=0;i<Q.size();i++) 72 { 73 sum|=Q[i]; 74 //cout<<sum<<endl; 75 if(sum==k)flg=1; 76 } 77 for(int i=0;i<Q.size();i++) 78 { 79 for(int j=0;j<34;j++) 80 { 81 if(pow(2,j)>k)break; 82 if((LL)pow(2,j)&Q[i])vis[j]++; 83 } 84 } 85 for(int i=0;i<34;i++) 86 { 87 if(vis[i])ans=min(ans,vis[i]); 88 } 89 if(ans==inf||!flg)ans=0; 90 cout<<ans<<endl; 91 #ifdef Local 92 cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl; 93 #endif 94 }