位运算,这道题怎么算啊
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位运算,这道题怎么算啊相关的知识,希望对你有一定的参考价值。
参考技术A i的值是八进制的0122,即二进制的0000000001010010j的值是十六进制的0xa4,即二进制的0000000010100100
<<的优先级高于&的优先级,所以i&j<<2等价于:
i&(j<<2)
即0000000001010010&(0000000010100100<<2)
0000000010100100<<2,是左移两位,变成0000001010010000
i&(j<<2)就是
0000000001010010&0000001010010000
&是按位与,对应位都是1,结果是1,否则为0
结果是:
00000000000010000,即十进制的16,所以结果是16追问
我算的也是16
但是呢!答案给的是80
追答如果答案不是16,那就是错误的,因为正确答案是16
参考技术B 十进制122换成二进制是0111 1010
十六进制a4换成二进制
1010 0100
相同是1,相异是0
0010 0001追问
那个<<2呢?
追答我不懂,没用过,猜测的意思就是按二进制输出
追问好吧
追答。
正解是16,我拿软件跑了一下
<<2是左移两位
0111 1010
1001 0000与
0001 0000是16
bzoj4300 绝世好题(位运算+DP)
为什么要写这道题呢?因为它是“绝世好题”。
题意:给定n个数,在其中找出一段子序列b,使得b[i]&b[i-1]!=0,求出满足条件的最长子序列长度。
输入:第一行:一个整数n,表示数列的个数。
第二行:n个整数,表示数列a。
输出:一行,一个整数,表示最长的子序列长度。
输入样例:
3
1 2 3
输出样例:
2
解析:若b[i]&b[i-1]!=0,即b[i]与b[i-1]在二进制下有一位相同且都为1。那么设dp[i]表示前i个数所能达到的最长子序列长度,那么在转移时只需枚举是从二进制下的第几位转移过来的便好了。由于在转移时还要枚举是从哪个位置转移过来的,所以时间复杂度为o(n^2log(n)),但由于每次进行转移时是在前面的状态中找一个最大的,所以显然可以用堆进行优化,时间复杂度(o(nlog(n)^2))。(这题其实有o(nlog(n))的做法,而且大家好像都是这么写的,可我做的时候没想到(果然我还是菜!))。
代码如下:
1 #include<cstdio> 2 #include<vector> 3 #include<queue> 4 using namespace std; 5 6 const int MAXN=100010; 7 int n,a[MAXN],dp[MAXN],ans; 8 vector <int> ve[MAXN]; 9 priority_queue <int> heap[33]; 10 11 int read(void) { 12 char c; while (c=getchar(),c<‘0‘ || c>‘9‘); int x=c-‘0‘; 13 while (c=getchar(),c>=‘0‘ && c<=‘9‘) x=x*10+c-‘0‘; return x; 14 } 15 16 void solve(int x,int p) { //预处理出二进制下1的个数 17 int bit=0; 18 while (x>0) { 19 bit++; 20 if (x&1) { 21 ve[p].push_back(bit); 22 } 23 x>>=1; 24 } 25 } 26 27 int main() { 28 n=read(); 29 for (int i=1;i<=n;++i) a[i]=read(); 30 for (int i=1;i<=n;++i) solve(a[i],i); 31 for (int i=1;i<33;++i) heap[i].push(0); 32 for (int i=1;i<=n;++i) { 33 for (int j=0;j<ve[i].size();++j) { 34 int u=ve[i][j]; 35 dp[i]=max(dp[i],heap[u].top()+1); //从堆中取出一个最大的进行转移 36 } 37 for (int j=0;j<ve[i].size();++j) //将这一个状态加入堆中 38 heap[ve[i][j]].push(dp[i]); 39 } 40 for (int i=1;i<=n;++i) //找出最长的子序列 41 for (int j=0;j<ve[i].size();++j) ans=max(ans,dp[i]); 42 printf("%d",ans); 43 return 0; 44 }
以上是关于位运算,这道题怎么算啊的主要内容,如果未能解决你的问题,请参考以下文章