【POI2008】bzoj1122 账本

2023-11-07 20:48
文章标签 账本 poi2008 bzoj1122

本文主要是介绍【POI2008】bzoj1122 账本,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Description

一个长度为n的记账单,+表示存¥1,-表示取¥1。现在发现记账单有问题。一开始本来已经存了¥p,并且知道最后账户上还有¥q。你要把记账单修改正确,使得
1:账户永远不会出现负数; 2:最后账户上还有¥q。你有2种操作: 1:对某一位取反,耗时x; 2:把最后一位移到第一位,耗时y。
Input

The first line contains 5 integers n, p, q, x and y (1 n 1000000,
0 p;q 1000000, 1 x;y 1000), separated by single spaces and
denoting respectively: the number of transactions done by Byteasar,
initial and final account balance and the number of seconds needed to
perform a single turn (change of sign) and move of transaction to the
beginning. The second line contains a sequence of n signs (each a plus
or a minus), with no spaces in-between. 1 ≤ n ≤ 1000000, 0 ≤ p ,q ≤
1000000, 1 ≤x,y ≤ 1000) Output

修改消耗的时间

首先考虑没有翻转操作。这样的话如果+太多就尽量把后面的+改成-,如果-太多就尽量把前面的-改成+【称为第一类修改】。然后需要考虑的位置就是前缀和最小的位置,如果那里小于零,就需要再把前面的一些-改成+,后面的+改成-【称为第二类修改】,这样是一定可以改过来的,因为只要把之前所有出现过的-都改成+最终的前缀和一定为正。
因为翻转和修改是没有关系的,不妨设先翻转再修改。
把序列变成一个环,枚举起点,也就是枚举翻转的次数。因为不管序列如何排布,第一类修改的方法都是相同的,所以在考虑第一次修改之前求出的最小前缀和,就是上面所说第一类修改完成之后的最小前缀和【不是数值相等,而是位置相同,也就是知道前者可以方便地O(1)知道后者】。用单调队列维护一下,很容易O(n)求出每个起点的最小前缀和。然后枚举起点,按照前面所说进行计算,需要计算的只是第二类修改的次数,这是可以O(1)列式计算的。
第一类修改会让和变化2,这很容易看出。但是,第二类修改同样会让前缀和变化2,这是需要注意的。

#include<cstdio>
#include<cstring>
#define LL long long
const LL oo=1e16;
int a[3000010],n,que[3000010];
LL sum[3000010],f[3000010];
char s[1000010];
LL abs(LL x)
{return x>0?x:-x;
}
LL min(LL x,LL y)
{return x<y?x:y;
}
int main()
{int i,j,k,p,q,hd,tl;LL num,temp,ans,u,v,x,y,z;scanf("%d%d%d%lld%lld",&n,&p,&q,&x,&y);scanf("%s",s+1);for (i=1;i<=n;i++)a[i]=s[i]=='+'?1:-1;for (i=n+1;i<2*n;i++)a[i]=a[i-n];for (i=1;i<2*n;i++)sum[i]=sum[i-1]+a[i];hd=1;tl=0;for (i=2*n-1;i;i--){if (hd<=tl&&que[hd]>i+n-1) hd++;while (hd<=tl&&sum[que[tl]]>=sum[i]) tl--;que[++tl]=i;f[i]=sum[que[hd]]-sum[i-1];}num=(p+sum[n]-q)/2;ans=oo;for (i=1;i<=n;i++){u=i==1?0:n+1-i;temp=u*y+abs(num)*x;v=num<0?p+f[i]-num*2:p+f[i];if (v<0) temp+=2*x*((1-v)/2);ans=min(ans,temp);}printf("%lld\n",ans);
}

这篇关于【POI2008】bzoj1122 账本的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/366194

相关文章

第六章、去中心网络、分布式账本、默克尔树

第六章、去中心网络、分布式账本、默克尔树 1、概述2、去中心网络2.1 金融去中心化分析 3、分布式账本4、默克尔树 1、概述 本章介绍区块链中的几个核心概念:去中心网络、分布式账本、默克尔树原理。 2、去中心网络 区块链采用的网络架构是去中心的p2p网络,网络中的节点分成2类:节点、轻客户端(钱包)。 节点:维持区块链网络运行的支撑。节点参与记账权的竞争,并记录着所有的账

Android手账本案例

功能描述: 该手账本app实现了注册、登录、记录收入、支出、查询、日记等功能,适合新手学习。 开发语言: java 技术框架: mvc 开发工具: AndroidStudio2.2,新手最好使用此版本搭建,不同版本修改配置比较繁琐 数据库 sqlite 程序截图 代码在公众号:师哥帮忙 中自行下载。

超级账本11:node.js SDK的使用

1.centOS7安装node.js 杀掉活跃的容器 官网https://nodejs.org/en/下载tar.xz包,然后解压 设置node为全局变量 设置npm为全局变量 查看版本 2.搭建网络 赋予执行权限 启动网络 进入容器 查看通道,已经存在 3.链码编写和测试

超级账本10:Java SDK的使用

1.centOS7安装node.js 杀掉活跃的容器 官网https://nodejs.org/en/下载tar.xz包,然后解压 设置node为全局变量 设置npm为全局变量 查看版本 2.搭建网络 赋予执行权限 启动网络 进入容器 查看通道,已经存在 3.链码编写和测试 编写nodeExample.go

超级账本08:hyperledger fabric完整案例

1.fabric开发流程 需求整理合约编写合约部署合约交互外部服务编写 2.需求分析 开发一个资产转让功能模块平台功能 用户开户和销户 资产登记,解决资产上链和用户绑定资产 资产转让,资产所有权的变更 查询功能,用户查询、资产查询、资产变更历史查

超级账本07:hyperledger fabric链码案例

1.链码入门 hello.go安装链码 实例化链码 调用链码 2.账户相关链码 payment.go安装链码 实例化链码 查询账户 转账 查询账户

超级账本06:hyperledger fabric智能合约

1.智能合约 执行环境安全隔离、不受第三方干扰链码 是fabric应用层的基石,是应用层与底层的桥梁 执行环境是一个独立的docker环境 通过gRPC协议与背书节点连接,只有背书节点才会运行链码 链码的生命周期 打包 安装 实例化

超级账本05:hyperledger fabric账本存储

1.账本存储概述 peer节点账本存储图如下 左边区块链是狭义上的区块存储,底层是一个文件系统,区块并不是存储在数据库,而是直接存储为文件右下角的区块索引用于查询区块,将区块属性与区块位置关联,例如根据区块哈希、高度、交易ID查询区块区块索引的实现使用了levelDB,是一个内嵌的数据库fabric中不是一个区块单独存一个文件,所以需要区块索引去查找右上角状态数据库是区块链上的最新数据 2.

超级账本04:hyperledger fabric共识排序

1.共识机制介绍 交易背书:客户端节点根据背书策略,选择背书节点,发送交易提案,背书节点调用智能合约执行模拟交易,执行完成后,经过签名背书,返回给客户端节点,整个过程是模拟的交易排序:排序节点接收已经签名背书的交易,确定交易顺序,将排好序的交易打包成区块,分发给其他组织主节点,排序节点不会去关心交易是否正确,只负责排序和打包区块交易验证:区块存储和交易验证不冲突,区块存储前进行交易验证,fabr

[POI2008] STA-Station/洛谷P3478(树形dp)

[ P O I 2008 ] S T A − S t a t i o n ( 树形 d p ) \Huge{[POI2008] STA-Station(树形dp)} [POI2008]STA−Station(树形dp) 题目链接:[P3478 POI2008] STA-Station - 洛谷 文章目录 题意思路标程 题意 给定一个 n n n个点的树,请求出一个结点,使得