题目:http://codeforces.com/problemset/problem/455/E

题意:给定数组a,及f的定义:

f[1][j] = a[j];  1 <= j <= n

f[i][j] = min(f[i-1][j-1], f[i-1][j]) + a[j];  2 <= i <= j <= n

给定q个询问,每个询问为l,r,求f[l][r]

My solution:

  1. 写一些小数据就可以发现,其实对于一个询问l,r,其实等价于:

从[r-l+1, r]这个区间内取l个数,使其和最小。但是比较特殊的是,一个数可以取多次,并且如果取了一个x,那么[x+1,r]间的所有数必须得取。

例如,对于n=3, a = {2, 1, 3}

询问l=3, r=3的取法有:3+3+3=9, 3+3+1=7, 3+1+1=5, 3+1+2= 6;答案为3+1+1=5

2.设答案f[l][r]的询问答案合法区间是在[x, r]这一段取得的,我们还可以发现如下的性质:

1)a[x]一定是[x,r]中最小的,否则存在 x<=y<=r, a[y] <= a[x],比[x,r]更优的区间[y, r]

除[y, r]的共同区间外,剩下的l-y-r个[y,r]区间可以全取a[y],显然比[x,r]更小

2)a[x+1]~a[y]各取一个,剩下的全取a[x],因为a[x]是区间最小元素,取越多答案越小

3.基于2我们可以维护一个递增的序列来求答案,但是这样还是不够,妥妥TlE

只能看下决策之间有什么关系了;

对于询问(l,r)不妨设两个决策k<j,并且决策k优于j

那么 (sum[r] - sum[k]) - (l - (r - k)) * a[k] <= (sum[r] - sum[j]) - (l - (r - j)) * a[j];

整理一下式子:

(sum[k] - a[k]*k) - (sum[j] - a[j]*j) / (a[k] - a[j]) <= l - r;

这不就是个斜率的式子,剩下的就是维护一个凸壳即可

4.具体的话对于询问按照r排序,然后离线做

然后二分一左边界,找到合法区间完,再二分找到合法的斜率。具体看代码吧

code:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cctype>
#include <ctime>
#include <utility>
#define M0(x) memset(x, 0, sizeof(x))
#define pb push_back
#define mp make_pair
#define x first
#define y second
#define vii vector< pair<int, int> >::iterator
using namespace std;
const int maxn = ;
vector< pair<int, int> > ask[maxn];
int n, m;
long long sum[maxn], ans[maxn];
int s[maxn], top, a[maxn]; inline double slope(int k, int j){
double yk = sum[k] - (double)k * a[k], yj = sum[j] - (double)j * a[j];
return (yk - yj) / (a[k] - a[j]);
} void init(){
for (int i = ; i <= n; ++i)
scanf("%d", a+i), sum[i] = sum[i-] + a[i];
for (int i = ; i <= n; ++i) ask[i].clear();
scanf("%d", &m);
int l, r;
for (int i = ; i < m; ++i){
scanf("%d%d", &l, &r);
ask[r].pb(mp(l, i));
}
} void solve(){
int top = ;
int l, r, mid, pos;
for (int i = ; i <= n; ++i){
while (top > && a[s[top]] >= a[i]) --top;
while (top > && slope(s[top], i) >= slope(s[top-], i)) --top;
s[++top] = i;
for (vii it = ask[i].begin(); it != ask[i].end(); ++it){
l = lower_bound(s+, s+top+, i-it->x+) - s;
r = top-, pos = i;
while (l <= r){
mid = (l + r) >> ;
if (slope(s[mid], s[mid+]) <= it->x - i) pos = s[mid], r = mid - ;
else l = mid + ;
}
ans[it->y] = sum[i] - sum[pos] + (long long)a[pos]*(it->x+pos-i);
}
}
for (int i = ; i < m; ++i)
printf("%I64d\n", ans[i]);
}
int main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
while (scanf("%d", &n) != EOF){
init();
solve();
}
return ;
}

codeforces 455E的更多相关文章

  1. @codeforces - 455E@ Function

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 已知 a 序列,并给定以下关系: \[\begin{cases} ...

  2. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  3. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  4. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  5. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  6. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  7. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  8. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

  9. CodeForces - 696B Puzzles

    http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...

随机推荐

  1. fis代码压缩

    Fis代码压缩步骤 1,安装fis(http://fis.baidu.com/fis3/docs/beginning/install.html) fis安装支持的node版本:0.8x,0.10x,0 ...

  2. (O)阻止默认事件和阻止冒泡的应用场景

    场景1:阻止默认事件   比如这样的一个需求 点击取消a标签按钮的时候会触发一些js动作,但是不能让这个a标签产生跳转行为, 所以需要在点击取消的时候 阻止冒泡,防止其跳转. <a id='ca ...

  3. 如何为linux系统设置全局的默认网络代理

    方法1:更改全局配置文件/etc/profile all_proxy="all_proxy=socks://proxy.xxx.com.cn:80/" ftp_proxy=&quo ...

  4. ubuntu下安装配置ADB

    1.下载SDK Tools for Linux,地址:http://developer.android.com/sdk/index.html 2.解压,将 android-sdk-linux 文件夹放 ...

  5. 三大框架中各种xml的存放位置

      web.xml中classpath:和classpath*:  有什么区别? classpath:只会到你的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar ...

  6. 复制粘贴容易犯的错误 eclipse

    有时候复制原有的代码到xml文件中,会提示某文件没有找到,一般该文件名字改成别的了,这时候为了解决这问题一般需要对这个文件重命名

  7. mybatis的批量操作

    foreach关键字: 批量查找/删除:用where id in<foreach> (xxx,yyy,zzz ...)</foreach> 批量更新:需要开启批量sql,比如d ...

  8. mysqldb mysql_config

    在安装mysqldb Python的时候会用到mysql_config,但是正常安装的MySQL环境下是没有这个文件的,这个文件在Linux下是可执行文件,所以需要到mysql官方网站上下载MySQL ...

  9. java JNI 实现原理 (二) Linux 下如何 load JNILibrary

    在博客java JNI (一)虚拟机中classloader的JNILibrary 中讨论了java中的Library 是由classloader 来load的,那我们来看看 classloader是 ...

  10. Codeforces gym 102062 简要题解

    文章目录 A. Bob and BoB B. Vibranium Gift C. The Blood Moon D. Palindrome and Chocolate E. Jumpy Robot F ...