码迷,mamicode.com
首页 > 其他好文 > 详细

[9.27模拟] 异或

时间:2017-09-29 22:59:50      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:++   efi   题意   col   dfs   names   ems   ==   lib   

 

题意:多组询问,每组询问给出一段区间[l,r]和一个数k,要求从[l,r]中选择不多于k个数,使得它们的异或和最小,输出最小的异或和、选取的数的个数,选取的数

 

题解:

大力分类讨论一波

1、k==1,sum=l

2、k==2,如果r==l+1,则sum=min(l,l^r),否则就是1

3、k==3,答案不会超过1,现在考虑找出三个数使得其异或和为0,设$x=2^{k-1}-1$,$y=2^{k-1}+2^k$,$z=y-1$,枚举k,若能在$[l,r]$中找到这个三个数,则sum=0

4、k==4,若r-l>=4,则若l为偶数,l^(l+1)^(l+2)^(l+3)=0,否则(l+1)^(l+2)^(l+3)^(l+4)=0,若r-l<4,则暴搜枚举子集即可

5、k>=5 sum=0

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<cmath>
  7 #define ll long long
  8 #define xx ((1ll<<k)-1)
  9 #define yy ((1ll<<(k-1))+(1ll<<k)-1)
 10 #define zz ((1ll<<(k-1))+(1ll<<k))
 11 using namespace std;
 12 
 13 int T,a[10];
 14 
 15 struct Node {
 16   int cnt;
 17   ll sum,s[10];
 18 }ans;
 19 
 20 void solve(ll l, ll r) {
 21   bool flg=0;
 22   for(int k=1; zz<=r; k++) {
 23     if(xx>=l) {
 24       printf("0 3\n%lld %lld %lld\n", (ll)xx,(ll)yy,(ll)zz);
 25       flg=1;
 26       break;
 27     }
 28   }
 29   if(!flg) {
 30     if((l&1ll)==0) printf("1 2\n%lld %lld\n", l,l+1);
 31     else printf("1 2\n%lld %lld\n", l+1,l+2);
 32   } 
 33 }
 34 
 35 void cal(Node &res, int deep, ll l) {
 36   Node ret;
 37   ret.sum=ret.cnt=0;
 38   for(int i=1; i<=deep; i++) {
 39     if(a[i]) {
 40       ret.sum^=(l+i-1);
 41       ret.cnt++;
 42       ret.s[ret.cnt]=(l+i-1);
 43     }
 44   }
 45   if(ret.sum<res.sum) res=ret;
 46 }
 47 
 48 void dfs(int dep, int deep, ll l) {
 49   if(dep==deep+1) {
 50     bool flg=0;
 51     for(int i=1; i<=dep; i++) {
 52       if(a[i]!=0) flg=1;
 53     }
 54     if(!flg) return;
 55     cal(ans,deep,l);
 56     return;
 57   }
 58   a[dep]=0,dfs(dep+1,deep,l);
 59   a[dep]=1,dfs(dep+1,deep,l);
 60 }
 61 
 62 void solve2(ll l, ll r) {
 63   ans.sum=1ll<<60,ans.cnt=0;
 64   memset(ans.s,0,10);
 65   dfs(1,r-l+1,l);
 66   printf("%lld %d\n", ans.sum,ans.cnt);
 67   for(int i=1; i<ans.cnt; i++) {
 68     printf("%lld ", ans.s[i]);
 69   }
 70   printf("%lld\n", ans.s[ans.cnt]);
 71 }
 72 
 73 int main() {
 74   scanf("%d", &T);
 75   while(T--) {
 76     ll l,r; int k;
 77     scanf("%lld%lld%d", &l,&r,&k);
 78     if(k==1) printf("%lld 1\n%lld\n", l,l);  
 79     else if(k==2) {
 80       if(r==l+1) {
 81     if(l<=(l^r)) printf("%lld 1\n%lld\n",l,l);
 82     else printf("%lld 2\n%lld %lld\n",l^r,l,r);
 83       }      
 84       else {
 85     if((l&1ll)==0) printf("1 2\n%lld %lld\n", l,l+1);
 86     else printf("1 2\n%lld %lld\n", l+1,l+2);    
 87       } 
 88     }
 89     else if(k==3) solve(l,r);
 90     else if(k==4) {
 91       if(r-l>=4) {
 92     if((l&1ll)==0) printf("0 4\n%lld %lld %lld %lld\n", l,l+1,l+2,l+3);    
 93     else printf("0 4\n%lld %lld %lld %lld\n", l+1,l+2,l+3,l+4);
 94       }
 95       else solve2(l,r);
 96     }
 97     else {
 98       if((l&1ll)==0) printf("0 4\n%lld %lld %lld %lld\n",l,l+1,l+2,l+3);
 99       else printf("0 4\n%lld %lld %lld %lld\n", l+1,l+2,l+3,l+4);
100     }
101   }
102   return 0;
103 }

 

[9.27模拟] 异或

标签:++   efi   题意   col   dfs   names   ems   ==   lib   

原文地址:http://www.cnblogs.com/HLXZZ/p/7612674.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!