HDU 5358 First One 求和(序列求和,优化)
题意:给定一个含n个元素的序列,求下式子的结果。S(i,j)表示为seq[i...j]之和。注:对于log20可视为1。数据量n<=105。

思路:即使能够在O(1)的时间内求得任意S,也是需要O(n*n)来求和的。
对于这种题,一般就是研究式子,看有什么办法可以减少复杂度。
看到式子中的向下取整符号了吗?很多数的取整结果是相同的,即使给个2147483647取整也只是30多而已(噗,忘了多少)。
而对于这个式子,S最大也不会超过longlong,确切计算,小于234。那么取log之后的范围这么小,如果能够知道分别有多少个的话,那就快多了。可以看得出对于同一个i,取log后的结果是呈线性的,从1到34逐步递增的(当然有可能没有那么大/小)。
那很好办,对于每个i,只需要将一整段“取log后向下取整的结果加1”为k的给截出来,统计k个(i,j)之和再乘以k不就是这一段的答案了吗?那么对于每个i,最多可能被截成34段啦。相比而言快了许多。复杂度为O(34*n)。
但是本题连这样的复杂度还是不行,还能继续优化,设
为k。
(1)先穷举k,k=[1,34].
(2)再穷举i。对于每个i,假设i-1中(i-1, R)这一段的结果为k,而i中答案为k的对应段必定大于等于这段(为什么?小学老师教的序列求和技术)。所以只需从上次穷举完之处继续往后判断即可,因为i比i-1少了个数字,说不定就变小了许多,再加几个不就补回来啦!
再具体的话就很难说清了,看代码注释吧。我看得懂相信你也可以。
#include <bits/stdc++.h>
#define INF 0x7f7f7f7f
#define pii pair<int,int>
#define LL long long
using namespace std;
const int N=;
LL sum[N], up[];
int cur[N];
void pre_cal()
{
sum[]=;
for(int i=; i<; i++) up[i]= (LL)<<i;
}
LL cal(int n)
{
for(int i=; i<=n; i++) cur[i]=i; //记录以i为下标的,穷举到那里了。 LL ans=;
int L=, R=;
for(int k=; k<; k++)
{
R=cur[];
for(int i=; i<=n; i++) //以i为下标的
{
L=cur[i];
R=max(cur[i], cur[i-]); //这一步决定了AC或者TLE
if(L>n) continue; //以i为下标的已经计算完毕。 while( R<=n && sum[R]-sum[i-]<up[k] ) R++; //找到(logx+1)为k的一段[L,R)
if(L<R)
{
cur[i]=R;
if((R-L)&) ans+=( (LL)(R-L)*i + (LL)(R-+L)/*(R-L) )*max(,k); //注意这里千万要转longlong
else ans+=( (LL)(R-L)*i + (LL)(R-+L)*(R-L)/ )*max(,k);
}
}
} return ans;
} int main()
{
freopen("input.txt", "r", stdin);
pre_cal();
int t, n;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(int i=; i<=n; i++)
{
scanf("%lld", &sum[i]);
sum[i] += sum[i-];
}
printf("%lld\n", cal(n));
}
return ;
}
AC代码
HDU 5358 First One 求和(序列求和,优化)的更多相关文章
- HDU 2254 奥运(矩阵高速幂+二分等比序列求和)
HDU 2254 奥运(矩阵高速幂+二分等比序列求和) ACM 题目地址:HDU 2254 奥运 题意: 中问题不解释. 分析: 依据floyd的算法,矩阵的k次方表示这个矩阵走了k步. 所以k ...
- HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和)
HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意: g(i)=k*i+b;i为变量. 给出 ...
- 51NOD 1258 序列求和 V4 [任意模数fft 多项式求逆元 伯努利数]
1258 序列求和 V4 题意:求\(S_m(n) = \sum_{i=1}^n i^m \mod 10^9+7\),多组数据,\(T \le 500, n \le 10^{18}, k \le 50 ...
- hdu 4288 离线线段树+间隔求和
Coder Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- 51nod 1258 序列求和 V4
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1258 1258 序列求和 V4 基准时间限制:8 秒 空间限制:131 ...
- 【51Nod1258】序列求和V4(FFT)
[51Nod1258]序列求和V4(FFT) 题面 51Nod 多组数据,求: \[Ans=\sum_{i=1}^ni^k,n\le 10^{18},k\le50000\] 题解 预处理伯努利数,时间 ...
- 51nod_1236_序列求和 V3 _组合数学
51nod_1236_序列求和 V3 _组合数学 Fib(n)表示斐波那契数列的第n项,Fib(n) = Fib(n-1) + Fib(n-2).Fib(0) = 0, Fib(1) = 1. (1, ...
- HDU 5358(2015多校联合训练赛第六场1006) First One (区间合并+常数优化)
pid=5358">HDU 5358 题意: 求∑i=1n∑j=in(⌊log2S(i,j)⌋+1)∗(i+j). 思路: S(i,j) < 10^10 & ...
- lqb 入门训练 序列求和 (PS:用长整数做数据的输入输出)
入门训练 序列求和 时间限制:1.0s 内存限制:256.0MB 问题描述 求1+2+3+...+n的值. 输入格式 输入包括一个整数n. 输出格式 输出一行,包括一个整数,表示1+2+3 ...
随机推荐
- POJ 1661 Help Jimmy (dijkstra,最短路)
刚在百度搜索了一下这道题的题解, 因为看到有别人用动态规划做的,所以想参考一下. 结果顺带发现了有那么几个网站,上面的文章竟然和我这篇一模一样(除了一些明显的错别字外),我去,作者还是同一个人Admi ...
- linux使用crontab实现PHP执行定时任务及codeiginter参数传递相关
http://www.phpddt.com/php/linux-crontab.html crontab: yum install crontabs //安装 说明: /sbin/service cr ...
- POJ 1477
#include <iostream> #define MAXN 100 using namespace std; int _[MAXN]; int main() { //freopen( ...
- mysql 存储过程事务支持回滚
如图查看表的属性: InnoDB 支持事务. MyISAM 不支持事务,不过性能更优越.
- 传说中的WCF(7):“单向”&“双向”
在WCF中,服务器与客户端的通讯有单向(单工)和双向(双工)之分.要说有什么形式上的表现,那就是单向与双向生成的SOAP不同,咱们先放下代码不说.但通常情况下,我们也不太需要去研究生成的SOAP是啥样 ...
- 由枚举模块到ring0内存结构 (分析NtQueryVirtualMemory)
是由获得进程模块而引发的一系列的问题,首先,在ring3层下枚举进程模块有ToolHelp,Psapi,还可以通过在ntdll中获得ZwQuerySystemInformation的函数地址来枚举,其 ...
- PowerDesigner 将CDM、PDM导出为图片
选中所有对象(Ctrl + A),复制(Ctrl + C),打开系统的“画图”软件,粘贴(Ctrl + V),另存为BMP或者PNG格式即可. 如果是将图片粘贴到Word文档也是可行的.
- Linux搜狗输入法在有道云笔记上输入冗余
Linux下,在有道云笔记中用搜狗拼音输入法时,会出现输入冗余,类似于输入法的缓冲上屏了.这是有道云笔记Web页面的问题. 暂时的解决办法是按Ctrl + alt + p. 不仅搜狗输入法,凡是用fc ...
- IE8 浏览器自动保存文档副本,添加缓存
若响应(response)HTTP头信息中没有关于缓存的头信息,则在IE8中第二次请求网页时,从缓存中拿取文件,而不是重新向服务器请求.而在Firefox或chrome则是重新向服务器请求. 解决方法 ...
- linux shell 命令学习(4) cut - remove sections from each line of files
之前写了split命令,split主要是按照行来进行文件的分割,而cut 是按照列来进行文件内容的选取 cut OPTION... [FILE]... 描述: 按列选取FILE的内容进行输出 -d : ...