YYHS-鏖战字符串
题目描述
输入
输出
样例输入
样例输出
提示
测试点编号
|
n
|
特殊约定
|
1
|
n≤10
|
所有的字母都是a
|
2
|
所有的字母都是a或b
|
|
3
|
|
|
4
|
||
5
|
n≤2000
|
所有的字母都是a
|
6
|
所有的字母都是a或b
|
|
7
|
l=1,r=n
|
|
8
|
|
|
9
|
||
10
|
||
11
|
n≤100000
|
l=1,r=n
|
12
|
||
13
|
||
14
|
||
15
|
l>r
|
|
16
|
||
17
|
|
|
18
|
||
19
|
||
20
|
题解
这道题刚开始只想到50分的方法
自己斜率优化不怎么会,过了好久才A
这道题如果没有第二种方法就是裸的斜率优化
所以我们先考虑第一种方法,通过计算,我们可以发现
若j>k且dp[j]+a*(sum[i]-sum[j])*(sum[i]-sum[j])+b>=dp[k]+a*(sum[i]-sum[k])*(sum[i]-sum[k])+b,就可以把k弹出
通过化简可得sum[i]*2*a*(sum[j]-sum[k])>=dp[j]-dp[k]+a*sum[j]*sum[j]-a*sum[k]*sum[k]
第一种方法做完后我们就考虑第二种方法
dp[i]=min(dp[j]+(sum[i]-sum[j])*c+d)=min(dp[j]-sum[j]*c+d+sum[i]*c)
而d+sum[i]*c是一个常数,所以我们之要维护一下dp[j]-sum[j]*c就可以了,这里我们可以用堆和单调队列
因为本人不怎么会单调队列,所以用了堆。
对于判断第二种的可行性,我们可以开一个n*26的数组,可以预处理出前i个字符中所有字符的出现次数
所以每次判断一段区间是否可行的时候只要常数次操作就可以了。
#include<bits/stdc++.h>
#define N 100005
#define ll long long
#define node pair<int,int>
using namespace std;
ll n,a,b,c,d;
int id,L,R,l,r;
int w[N]['z'+];
int h[N];
ll di[N],dp[N];
char s[N];
priority_queue<node,vector<node>,greater<node> > q;
bool calc(int i,int j,int k){
return di[i]**a*(di[j]-di[k])>=dp[j]-dp[k]+a*di[j]*di[j]-a*di[k]*di[k];
}
bool cal(int i,int j,int k){
return (di[j]-di[k])*(dp[i]-dp[j]+a*di[i]*di[i]-a*di[j]*di[j])<=(di[i]-di[j])*(dp[j]-dp[k]+a*di[j]*di[j]-a*di[k]*di[k]);
}
bool ok(int id,int i){
int s=-1e8;
for (int j='a';j<='z';j++)
s=max(s,w[i][j]-w[id][j]);
if (s>=L&&s<=R) return true;
return false;
}
int main(){
scanf("%lld%lld%lld%lld%lld%d%d",&n,&a,&b,&c,&d,&L,&R);
scanf("%s",s+);
for (int i=;i<=n;i++){
for (int j='a';j<='z';j++) w[i][j]=w[i-][j];
w[i][s[i]]++;
}
for (int i=;i<=n;i++)
scanf("%lld",&di[i]),di[i]+=di[i-];
l=; r=; id=;
for (int i=;i<=n;i++){
while (l<r&&calc(i,h[l+],h[l])) l++;
dp[i]=dp[h[l]]+a*(di[i]-di[h[l]])*(di[i]-di[h[l]])+b;
while (id<=i)
if (ok(id,i)){
q.push(make_pair(dp[id]-c*di[id],id));
id++;
} else break;
while (!q.empty()){
int f=q.top().second;
if (ok(f,i)){
dp[i]=min(dp[i],dp[f]+c*(di[i]-di[f])+d);
break;
} else{ q.pop(); continue; }
}
printf("%lld\n",dp[i]);
while (l<r&&cal(i,h[r],h[r-])) r--;
h[++r]=i;
}
return ;
}
YYHS-鏖战字符串的更多相关文章
- 【NOIP2017练习】鏖战字符串(斜率优化DP)
题意: 在决胜局中,Abwad决定和nbc鏖战字符串,比的是谁能更快地将一个“量子态的字符串”删除.“量子态的字符串”的每个字符都有一个删除难度dif[i].“量子态的字符串”非常顽固,只能先分割成若 ...
- 校际联合Contest
每次开一个坑都像是重新被碾压的预感 最近的新闻,以前很喜欢乔任梁的<复活>...然后他就死了...感觉我再多愁善感一点的话...就要悲伤逆流成河了吧... Contest 09/24(乐滋 ...
- 转:鏖战双十一-阿里直播平台面临的技术挑战(webSocket, 敏感词过滤等很不错)
转自:http://www.infoq.com/cn/articles/alibaba-broadcast-platform-technology-challenges 鏖战双十一-阿里直播平台面临的 ...
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率
之前一篇里写过字符串常用类的三种方式<java中的字符串相关知识整理>,只不过这个只是分析并不知道他们之间会有多大的区别,或者所谓的StringBuffer能提升多少拼接效率呢?为此写个简 ...
- java中的字符串相关知识整理
字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...
- JavaScript 字符串实用常操纪要
JavaScript 字符串用于存储和处理文本.因此在编写 JS 代码之时她总如影随形,在你处理用户的输入数据的时候,在读取或设置 DOM 对象的属性时,在操作 Cookie 时,在转换各种不同 Da ...
- Java 字符串格式化详解
Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...
- Redis的简单动态字符串实现
Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串), 而是自己构建了一种名为简单动态字符串(simple dynamic string,sds)的抽象类 ...
随机推荐
- Git初学二(SSH免密)
在管理Git项目上,初学者使用HTTPS直接克隆项目到本地是最方便的.但是之后的fetch和push代码需要输入账号和密码也是比较烦的. 这章在上一章的基础上,将HTTPS切换成SSH.SSH的优点就 ...
- mysql alter使用
修改表名: ALTER TABLE Table_name_A RENAME TO Table_name_B; //增加主键 alter table tabelname add new_field_i ...
- zoj3777 Problem Arrangement
The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward i ...
- Struts:文件上传下载
- Linux常用命令简单总结
Liunx常用命令 1. 文件及目录管理 1.1. ls:显示目录 参数及说明 空:补显示隐含文件 -a:显示所有文件 -l:显示详细列表 1.2. chgrp:设置文件组(root权限) 用法示例 ...
- JVM(一) OpenJDK1.8源码在Ubuntu16.04下的编译
笔者最近在学习周志明老师编写的<深入理解Java虚拟机>一书,书中第一章的实战部分就是"自己编译JDK",不过书中提到的是OpenJDK 7的编译.由于现在Java开发 ...
- Android studio 1.x 安装完毕后无法打开问题解决方案
Android Studio 1.0正式发布,给Android开发者带来了不小的惊喜,再也不用为繁琐的环境配置而烦恼,从某一层面上说这降低了android开发门槛. 不过貌似只能开心一会儿,因为and ...
- RAISERROR
RAISERROR 可以抛出一个错误,并被程序捕获,在存储过程经常使用: 是否进入Catch代码执行区域,在于错误严重等级设置 RAISERROR ('无效数据', 11 , 1) 第一个参数:自定义 ...
- 在数组a中,a[i]+a[j]=a[k],求a[k]的最大值,a[k]max——猎八哥fly
在数组a中,a[i]+a[j]=a[k],求a[k]的最大值,a[k]max. 思路:将a中的数组两两相加,组成一个新的数组.并将新的数组和a数组进行sort排序.然后将a数组从大到小与新数组比较,如 ...
- Java 多线程(一) 基础知识与概念
多线程Multi-Thread 基础 线程概念 线程就是程序中单独顺序的流控制. 线程本身不能运行,它只能用于程序中. 说明:线程是程序内的顺序控制流,只能使用分配给程序的资源和环境. 进程 进程:执 ...