[9.27模拟] 异或

Posted HLX_Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[9.27模拟] 异或相关的知识,希望对你有一定的参考价值。

 

题意:多组询问,每组询问给出一段区间[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模拟] 异或的主要内容,如果未能解决你的问题,请参考以下文章

9.27NOIP模拟题

9.27 noip模拟试题

9.27考试 SD_le NOIP模拟题 第三题 建造游乐场题解

LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段

9.29 接9.27PHP相关

模拟1486. 数组异或操作