HDU 5358 First One(枚举)
来源:互联网 发布:成都市软件行业协会 编辑:程序博客网 时间:2024/05/23 11:19
First One
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 690 Accepted Submission(s): 205
Problem Description
soda has an integer array a1,a2,…,an . Let S(i,j) be the sum of ai,ai+1,…,aj . Now soda wants to know the value below:∑i=1n∑j=in(⌊log2S(i,j)⌋+1)×(i+j)
Note: In this problem, you can considerlog20 as 0.
Note: In this problem, you can consider
Input
There are multiple test cases. The first line of input contains an integer T , indicating the number of test cases. For each test case:
The first line contains an integern (1≤n≤105) , the number of integers in the array.
The next line containsn integers a1,a2,…,an (0≤ai≤105) .
The first line contains an integer
The next line contains
Output
For each test case, output the value.
Sample Input
121 1
Sample Output
12
Source
2015 Multi-University Training Contest 6
解题思路:因为0<=ai<=10^5,0<n<=10^5,所以0<=S(i,j)<10^12<2^34,设k=⌊log2S(i,j)⌋+1则1<=k<=34,那么我们
每次枚举k时,求解出所有符合条件的(i+j),求和即可。
而对于每一个k,求解(i+j)时,先预处理出s[i](s[i]=a1+……+ai,则sum(i,j)=s[j]-s[i-1]),那么接下来只需找到所有
满足2^(k-1)<=sum(i,j)<=2^k-1的(i+j)即可。
对于求(i+j),我们再次枚举i,对每一个i,求解出j的一个区间[l,r],使得对当前的i,有当l<=j<=r时,2^(k-1)
<=sum(i,j)<=2^k-1成立。那么对于当前的k,i,满足条件的i,j区间为[i,j](l<=j<=r),这些区间对应同一个k和同一个i,这些区间的(i+j)的总和为:i*(r-l+1)+(r+l)*(r-l+1)/2。
枚举完所有的k和i,将所有和累加。
对于求解区间[l,r],假设k=a,在枚举i=b时,得到j的区间[L1,R1],那么相同的k,在枚举i=b+1时,得到j的区间[L2,R2]
一定不在区间[L1,R1]的左边,简单的说就是L2>L1,R2>R1。因此查找l,r时可以减少范围。
代码如下:
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <iostream>#include <algorithm>#include <string>#include <vector>#include <deque>#include <list>#include <set>#include <map>#include <stack>#include <queue>#include <numeric>#include <iomanip>#include <bitset>#include <sstream>#include <fstream>#include <limits.h>#define debug "output for debug\n"#define pi (acos(-1.0))#define eps (1e-6)#define inf (1<<28)#define sqr(x) (x) * (x)#define mod 1000000007using namespace std;typedef long long ll;typedef unsigned long long ULL;ll fl[35]={0,0,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592};ll fr[35]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535,131071,262143,524287,1048575,2097151,4194303,8388607,16777215,33554431,67108863,134217727,268435455,536870911,1073741823,2147483647,4294967295,8589934591,17179869183};ll s[100005];int main(){ ll i,j,k,n,a,l,r,t; scanf("%I64d",&t); while(t--) { scanf("%I64d",&n); for(i=1;i<=n;i++) { scanf("%I64d",&a); s[i]=s[i-1]+a; } ll ans=0; for(k=1;k<=34;k++) { l=1; r=0; //移位操作控制sum(i,j)的范围,也可以用数组 //fl= k==1?0:(1ll<<(k-1));fr=(1ll<<k)-1; for(i=1;i<=n;i++) { l=max(i,l); while(l<=n&&s[l]-s[i-1]<fl[k])//while(l<=n&&s[l]-s[i-1]<fl) l++; r=max(l-1,r); while(r+1<=n&&s[r+1]-s[i-1]>=fl[k]&&s[r+1]-s[i-1]<=fr[k])//while(r+1<=n&&s[r+1]-s[i-1]>=fl[k]&&s[r+1]-s[i-1]<=fr) r++; if(l<=r) ans+=(i*(r-l+1)+(r+l)*(r-l+1)/2)*k; //ans+=(i+l+i+r)*(r-l+1)/2*k; } } printf("%I64d\n",ans); } return 0;}
0 0
- HDU 5358 First One(枚举)
- HDU 5358 First One(枚举)
- HDU 5358 First One(枚举+尺举法)
- hdu 5358 First One [枚举+尺取法]
- 多校第六场 1006 hdu 5358 First One(枚举)
- HDU 5358 First One
- HDU 5358 First One
- HDU 5358 First One
- hdu 5358 First One(想法题)
- hdu 5358 First One(二进制+twopoint)
- 数学题(First One,HDU 5358)
- hdu 5358 First One (2015多校第六场第6题)尺取法枚举区间和
- 【瞎搞】 HDU 5358 First One
- hdu 5358 First One 数学
- hdu 5358 First One 2015多校联合训练赛#6 枚举
- HDU 5358 多校第6场 First One
- hdu 5358 First One (尺取法)
- HDU 5358 First One(尺取法)
- 如何反编译APK
- Shell脚本与vi编辑器
- Oulipo
- 【VBA研究】VBA数据类型定义和管控
- PagerTabStrip和PagerTitleStrip
- HDU 5358 First One(枚举)
- 使用多线程
- Android虚拟机访问tomcat服务器下的文件
- 快速排序
- 现代软件工程的教材和参考书
- MySQL数据库表名、列名、别名区分大小写的问题及解决
- Blog开篇
- ios xcode 下 报出 ”xx“is missing from working copy 的问题
- 单例模式优缺点