Magician and Pigs

分析一下三个操作分别干了些什么

  1. 新添一只猪
  2. 使血量为 \(x\) 的猪血量变为 \(\max(x-v,0)\)
  3. 设前面操作后猪总共会受到 \(s\) 的伤害,复制一只血量为 \(\max(x-s,0)\) 的猪,使 \(s=s\times 2\)

根据操作 \(3\) 可得最多 \(\log x\) 次操作后会杀死任何一只复制的猪,此时复制变得没有任何意义。当没有任何操作 \(2\) 时,操作 \(3\) 变成了使猪的数量翻倍。所以考虑倒着做,处理每只猪最后能剩下多少猪。

预处理出每次操作 \(2/3\) 会造成多少伤害,对于操作 \(1\),若它后面产生的伤害已经超过这只猪的血量,显然不会有任何贡献。先去掉操作 \(2\) 造成的伤害,再考虑操作 \(3\) 造成的伤害。如果倒过来的第 \(i\) 次操作 \(3\) 造成 \(x\) 伤害能吃下来,那么前面所有伤害之后都能吃下来,因为每次伤害至少翻倍,那一只猪会变为 \(2^{cnt-i}\) 只猪,\(cnt\) 表示这次操作 \(1\) 后面共有 \(cnt\) 次操作 \(3\)。这是没有复制的猪承受伤害能增加的数量,还有复制出来的猪承受伤害能增加的数量,所以将血量减去 \(x\),再往前找。因为最多找 \(log x\) 次,所以复杂度为 \(O(n\log x)\)。

点击查看代码
#include<bits/stdc++.h>
#define ull unsigned long long
#define int long long
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
using namespace std;
namespace IO{
template<typename T>
inline void read(T &x){
x=0;
int f=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-'){
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+(ch-'0');
ch=getchar();
}
x=(f==1?x:-x);
}
template<typename T>
inline void write(T x){
if(x<0){
putchar('-');
x=-x;
}
if(x>=10){
write(x/10);
}
putchar(x%10+'0');
}
template<typename T>
inline void write_endl(T x){
write(x);
putchar('\n');
}
template<typename T>
inline void write_space(T x){
write(x);
putchar(' ');
}
}
using namespace IO;
const int N=8e5+10,mx=1e9,mod=998244353;
int n,m,opt[N],val[N],c[N],cnt,s[N],d[N],tot,sum,res=1,ans;
void solve(){
read(n);
for(int i=1;i<=n;i++){
read(opt[i]);
if(opt[i]!=3){
read(val[i]);
}
if(opt[i]==2){
sum+=val[i];
}
if(opt[i]==3){
val[i]=sum;
sum*=2;
}
sum=min(sum,mx);
}
sum=0;
for(int i=n;i;i--){
if(opt[i]==2){
sum+=val[i];
}
if(opt[i]==3){
if(val[i]==mx){
continue;
}
if(!val[i]){
res=res*2%mod;
continue;
}
c[++cnt]=val[i];
}
else{
val[i]-=sum;
if(val[i]<=0){
continue;
}
int S=0;
for(int j=1;j<=cnt;j++){
if(val[i]>c[j]){
S=(S+(1ll<<(cnt-j))%mod)%mod;
val[i]-=c[j];
}
}
ans=(ans+(S+1)*res)%mod;
}
}
write_endl(ans);
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
int t=1;
while(t--){
solve();
}
return 0;
}

cf1774f解题报告的更多相关文章

  1. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  2. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  3. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  4. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  5. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

  6. 习题: codevs 2492 上帝造题的七分钟2 解题报告

    这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...

  7. 习题:codevs 1519 过路费 解题报告

    今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...

  8. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

  9. LeetCode 解题报告索引

    最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中......                        ...

  10. ACM: Just a Hook 解题报告 -线段树

    E - Just a Hook Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   D ...

随机推荐

  1. linux下文件重命名

    Ubuntu下执行上面举例的重命名时,命令是这样的:rename 's/a/xxx/g' *.txt

  2. 如何像Facebook一样构建数据中心 – BGP在大规模数据中心中的应用(3)

    如何像Facebook一样构建数据中心 – BGP在大规模数据中心中的应用(3) superrace• 18-06-12 作者简介:史梦晨,曾就职于国内金牌集成商, 现就职于EANTC( 欧洲高级网络 ...

  3. syn flood

    from scapy.all import * import random # 生成随机的IP def randomIP(): ip = ".".join(map(str, (ra ...

  4. 01.html大致主体格式

    <!DOCTYPE html> 不是HTML标签,就是文档声明标签 告诉浏览器使用哪种html版本来显示网页,其必须在文档中的最前面位置,要放在<html>标签之前, < ...

  5. 使用Wireshark查看HTTPS中TLS握手过程

    通过使用Wireshark抓包分析TLS握手的过程,可以更容易理解和验证TLS协议,本文将先介绍Wireshark解密HTTPS流量的方法,然后分别验证TLS握手过程和TLS会话恢复的过程. 一.使用 ...

  6. Qt 学习笔记 - 第三章 - Qt的三驾马车之一 - 串口编程 + 程序打包成Windows软件

    Qt 学习笔记全系列传送门: Qt 学习笔记 - 第一章 - 快速开始.信号与槽 Qt 学习笔记 - 第二章 - 添加图片.布局.界面切换 [本章]Qt 学习笔记 - 第三章 - Qt的三驾马车之一 ...

  7. Linux值得收藏的40个命令总结,常用的正则表达式

    1 删除0字节文件 find -type f -size 0 -exec rm -rf {} \; 2 查看进程 按内存从大到小排列 PS -e -o "%C : %p : %z : %a& ...

  8. 安装node.js教程------深入使用Vue

    教程 1.下载nodejs引擎 网址:https://nodejs.org/en/download/ 选择32-bit或者64-bit都行 2.下载最新版npm.zip压缩包 网址:http://no ...

  9. 有奖征文活动:从 RTC 到 RTE,从音视频到「实时万象」!

    Hi 小伙伴们, 社区已经更名 RTE 两个月辣-大家对于 RTC 和 RTE 的区分,是否还有疑惑呢? 关于这两者的区别,我们创始人兼 CEO 赵斌老师说: "RTC(实时音视频)从 Co ...

  10. Hive 与 HBase 之间的区别和联系

    首先要知道 Hive 和 HBase 两者的区别,我们必须要知道两者的作用和在大数据中扮演的角色 概念 Hive 1.Hive 是 hadoop 数据仓库管理工具,严格来说,不是数据库,本身是不存储数 ...