Subarrays Beauty (位运算)解题报告
2018-03-19 10:34
260 查看
A. Subarrays Beautytime limit per test1.0 smemory limit per test256 MBinputstandard inputoutputstandard outputYou are given an array a consisting of n integers. A subarray (l, r) from array a is defined as non-empty sequence of consecutive elements al, al + 1, ..., ar.The beauty of a subarray (l, r) is calculated as the bitwise AND for all elements in the subarray:Beauty(l, r) = al & al + 1 & al + 2 & ... & arYour task is to calculate the summation of the beauty of all subarrays (l, r) (1 ≤ l ≤ r ≤ n):
InputThe first line contains an integer T, where T is the number of test cases.The first line of each test case contains an integer n (1 ≤ n ≤ 105), where n is the size of the array a.The second line of each test case contains n integers a1, a2, ..., an (1 ≤ ai ≤ 106), giving the array a.OutputFor each test case, print a single line containing the summation of the beauty of all subarrays in the given array.ExampleinputCopy
(7) + (7 & 11) + (7 & 11 & 9) + (11) + (11 & 9) + (9) = 40
http://codeforces.com/gym/101532/problem/A
题意:给定长度为n的数,要求求所有子区间内的数进行与运算(&)的和;解题报告:
对于一个数来说变成二进制的后可以变成二进制数位之和,例如: 7=1*2^0+1*2^1+1*2^2; 11=1*2^0+1*2^1+0*2^3+1*2^4;因此根据与运算特性一旦出现了0&前面的数一定会变成0,要重新开始算,再讨论所有区间就完了。拿样例1来说:a[1]=7,a[2]=9,a[3]=11可以看成a[1]=0111a[2]=1001a[3]=1011对于二进制第j位a[i][j-1],假设在区间(l,r)都是连续的1,因此这个区间内1的个数是(r-l+1)*(r-l+2)/2。我们看看样例的第一个二进制位是111,区间是(1,3),它的子区间分别是(1,1)(1,2)(1,3)(2,2)(2,3)(3,3)也可以写成(1,1)(2,1)(2,2)(3,1)(3,2)(3,3)(这里只是数的方向不同),因此公式就出来了。下面代码(里面有个通过对数直接取最大二进制位数的优化,不知道为什么我用C++一定会超时,换了c直接a了)
InputThe first line contains an integer T, where T is the number of test cases.The first line of each test case contains an integer n (1 ≤ n ≤ 105), where n is the size of the array a.The second line of each test case contains n integers a1, a2, ..., an (1 ≤ ai ≤ 106), giving the array a.OutputFor each test case, print a single line containing the summation of the beauty of all subarrays in the given array.ExampleinputCopy
2 3 7 11 9 4 11 9 6 11output
40 48NoteAs input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printfinstead of cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.A bitwise AND takes two equal-length binary representations and performs the logical AND operation on each pair of the corresponding bits, by multiplying them. Thus, if both bits in the compared position are 1, the bit in the resulting binary representation is 1 (1 × 1 = 1); otherwise, the result is 0 (1 × 0 = 0 and 0 × 0 = 0). This operation exists in all modern programming languages, for example in language C++ and Java it is marked as &.In the first test case, the answer is calculated as summation of 6 subarrays as follow:Beauty(1, 1) + Beauty(l, 2) + Beauty(1, 3) + Beauty(2, 2) + Beauty(2, 3) + Beauty(3, 3)
(7) + (7 & 11) + (7 & 11 & 9) + (11) + (11 & 9) + (9) = 40
http://codeforces.com/gym/101532/problem/A
题意:给定长度为n的数,要求求所有子区间内的数进行与运算(&)的和;解题报告:
对于一个数来说变成二进制的后可以变成二进制数位之和,例如: 7=1*2^0+1*2^1+1*2^2; 11=1*2^0+1*2^1+0*2^3+1*2^4;因此根据与运算特性一旦出现了0&前面的数一定会变成0,要重新开始算,再讨论所有区间就完了。拿样例1来说:a[1]=7,a[2]=9,a[3]=11可以看成a[1]=0111a[2]=1001a[3]=1011对于二进制第j位a[i][j-1],假设在区间(l,r)都是连续的1,因此这个区间内1的个数是(r-l+1)*(r-l+2)/2。我们看看样例的第一个二进制位是111,区间是(1,3),它的子区间分别是(1,1)(1,2)(1,3)(2,2)(2,3)(3,3)也可以写成(1,1)(2,1)(2,2)(3,1)(3,2)(3,3)(这里只是数的方向不同),因此公式就出来了。下面代码(里面有个通过对数直接取最大二进制位数的优化,不知道为什么我用C++一定会超时,换了c直接a了)
#include<iostream> #include<stdio.h> #include<bitset> #include<cmath> using namespace std; const int maxn=1e5+5; bitset<31>a[maxn]; int main() { int T; while(scanf("%d",&T)!=EOF) { while(T--) { int n,temp; int set=0; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&temp); set=max(set,(int)log2(temp)+1); a[i]=bitset<31>(temp); } long long ans=0; a =bitset<31>(0); for(int i=0;i<set;i++) { long long rco=0; int flag=0; // cout<<"+++++++=flag="<<flag<<endl; for(int j=0;j<n+1;j++) { if(flag==0) { if(a[j][i]==1) { rco++; flag=1; } } else { if(a[j][i]==1) { rco++; } else { flag=0; ans+=(1<<i)*(long long)rco*(rco+1)/2; rco=0; } } // cout<<"j="<<j<<" "<<"flag="<<flag<<" "<<rco<<" "<<ans<<endl; } // cout<<"--------------------"<<endl; } cout<<ans<<endl; } } }
相关文章推荐
- [BZOJ1151][CTSC2007]动物园zoo 解题报告|DP|位运算
- leetCode解题报告之SingleNumberI,II(知识点:位运算)
- Leetcode 371. Sum of Two Integers 位运算实现加法 解题报告
- Uva 106 - Fermat vs. Pythagoras 解题报告
- SDUT 3460 Fighting_小银考呀考不过四级 (递推) -- 解题报告
- SOJ Dollars 解题报告
- [汇总]字符串题目推荐及解题报告
- [Leetcode] 155. Min Stack 解题报告
- [leetcode] 7. Reverse Integer 解题报告
- POJ2553 The Bottom of a Graph Tarjan 矩阵 pascal 解题报告
- 111120周赛解题报告
- HDOJ-5194-DZY Loves Balls 解题报告
- NHIP(2015)解题报告(第3题)
- Sicily 1146. 采药 解题报告(0-1背包问题)
- COGS 116. [NOIP2006] 能量项链 解题报告
- [dp问题] Poj 1014 & Zoj 1149 (Dividing) 解题报告(转)
- Codeforces Beta Round #95 (Div. 2) 部分解题报告 (dp,组合数,)
- c语言解题报告模板
- Hdu 1560 解题报告 迭代加深搜索
- LeetCode 165. Compare Version Numbers 解题报告