博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 5358 多校第6场 First One
阅读量:5337 次
发布时间:2019-06-15

本文共 2782 字,大约阅读时间需要 9 分钟。

First One

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 672    Accepted Submission(s): 193


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=1nj=in(log2S(i,j)+1)×(i+j)
Note: In this problem, you can consider 
log20 as 0.
 

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 integer 
n 
(1n105), the number of integers in the array.
The next line contains 
n integers 
a1,a2,,an 
(0ai105).
 

Output
For each test case, output the value.
 

Sample Input
 
1 2 1 1
 

Sample Output
 
12
 

Source

首先题意不是啥问题,就是给你个数组,让你求那个式子,s表示i到j的和。

比赛的时候想了个带二分的,就是统计log2可能出现的可能,一共同拥有34种,然后求一个前缀和,前缀和是递增的,能够二分。就写了

复杂度没算好,以为33*n*log(n)能过。结果跪了一下午,昨天就这么愉快的跪了

赛后题解上说用俩指针扫一遍,不得不吐槽一下。MD题解都是英文的。

联想到一次bestcoder 有一个题是求一共序列中两个数的和模上一个数最大,我以前的做法就是排序二分。而正解就是俩指针扫一遍,然而我没有记住

这个题就卡这个log(n)然而我就是过不去,诶。还是思维被限制住了

今天上午搞了个33 * n的

思路:

把数组处理成 前缀和,把log分类,有35种情况,题中吧log(0) 规为0。须要特判,题中给的最大的sum值为10^10,所以有35种情况,

那么就分情况讨论,一层循环。里面就是枚举n。然后找到两个值一个是sum[i-1] + 2^j的位置。另一个是sum[i-1]+2^(j+1)的位置,这段区间内的log值就全为j,用等差数列求和公式就能瞬间算出来这段区间的值,并且仅仅须要两个标记扫一遍。为何能够仅仅扫一遍呢,sum数组的值是递增的。须要找的值也是递增的。所下面次找的时候仅仅须要在上次寻找的后面继续接上就OK

/****************************************** 2015 Multi-University Training Contest 6** 1006 First One** HDU 5358** by calamity_coming**************************************/#include 
using namespace std;typedef long long ll;const int MAX_LONG = 1E5;ll a[MAX_LONG + 10];ll sum[MAX_LONG + 10];ll cf2[40];void init(){ ll k = 1; for(int i=0; i<=34; ++i) { cf2[i] = (k<<(i)); }}int main(){ init(); int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); sum[0] = 0; for(int i=1; i<=n; ++i) { scanf("%I64d",&a[i]); sum[i] = sum[i-1] + a[i];//前缀和处理 } sum[n+1] = 1E17; ll ans = 0; //0 for(int i=1; i<=n; ++i)//0比較特殊。要特殊的干 { int p = i; while(sum[p]==sum[i-1] && p<=n+1) { ++p; } --p; if(p>=i) { ans += (ll)(i*3+p)*(ll)(p-i+1)/2; } } for(int j=0; j<=33; ++j)//这是每一个情况 { int p1 = 0,p2 = 0;//用两个指针扫一遍 for(int i=1; i<=n; ++i)//当i递增时,新的p1,p2一定在后面 { ll adc = sum[i-1] + cf2[j]; while(sum[p1]
=p1 && p2) { ans += (j+1)*(ll)(i*2+p1+p2)*(ll)(p2-p1+1)/2; } } } printf("%I64d\n",ans); } return 0;}

转载于:https://www.cnblogs.com/yfceshi/p/6905876.html

你可能感兴趣的文章
poj 题目分类
查看>>
windows 安装yaml支持和pytest支持等
查看>>
读书笔记:季羡林关于如何做研究学问的心得
查看>>
面向对象的优点
查看>>
套接口和I/O通信
查看>>
阿里巴巴面试之利用两个int值实现读写锁
查看>>
浅谈性能测试
查看>>
Winform 菜单和工具栏控件
查看>>
CDH版本大数据集群下搭建的Hue详细启动步骤(图文详解)
查看>>
巧用Win+R
查看>>
浅析原生js模仿addclass和removeclass
查看>>
Python中的greenlet包实现并发编程的入门教程
查看>>
java中遍历属性字段及值(常见方法)
查看>>
深入理解jQuery框架-框架结构
查看>>
YUI3自动加载树实现
查看>>
python知识思维导图
查看>>
当心JavaScript奇葩的逗号表达式
查看>>
App Store最新审核指南(2015年3月更新版)
查看>>
织梦MIP文章内容页图片适配百度MIP规范
查看>>
[Kali_BT]通过低版本SerialPort蓝牙渗透功能手机
查看>>