CF1591F 题解
先不管值域,设计状态 \(dp_{i,j}\) 表示考虑前 \(i\) 个数最后一个数为 \(j\) 的方案数,那么有如下转移:
\]
先滚动数组去掉一维状态,然后发现每一次操作对于数组 \(dp\) 而言其实是对于 \(j \leq a_i\) 的 \(dp_{j}\) 变成 \(x - dp_j\) 这里 \(x\) 代表所有 \(dp_i\) 的总和,使得 \(j > a_i\) 的 \(dp_j\) 变为 \(0\)。
因此考虑用线段树维护 \(dp\) 数组即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 2e5+114;
const int top = 1e9+7;
const int mod = 998244353;
struct Node{
int sum,tag1,tag2,ls,rs,lt,rt;
}tr[maxn*40];
int tot,rt;
void pushup(int cur){
tr[cur].sum=(tr[tr[cur].ls].sum+tr[tr[cur].rs].sum)%mod;
}
void pushdown1(int cur){
if(tr[cur].tag1!=0){
int mid=(tr[cur].lt+tr[cur].rt)>>1;
if(tr[cur].ls==0) tr[cur].ls=++tot,tr[tr[cur].ls].tag2=1,tr[tr[cur].ls].lt=tr[cur].lt,tr[tr[cur].ls].rt=mid;
if(tr[cur].rs==0) tr[cur].rs=++tot,tr[tr[cur].rs].tag2=1,tr[tr[cur].rs].lt=mid+1,tr[tr[cur].rs].rt=tr[cur].rt;
tr[tr[cur].ls].sum=(tr[tr[cur].ls].sum+tr[cur].tag1*(mid-tr[cur].lt+1))%mod;
tr[tr[cur].rs].sum=(tr[tr[cur].rs].sum+tr[cur].tag1*(tr[cur].rt-mid))%mod;
tr[tr[cur].ls].tag1=(tr[tr[cur].ls].tag1+tr[cur].tag1)%mod;
tr[tr[cur].rs].tag1=(tr[tr[cur].rs].tag1+tr[cur].tag1)%mod;
tr[cur].tag1=0;
}
}
void pushdown2(int cur){
if(tr[cur].tag2!=1){
int mid=(tr[cur].lt+tr[cur].rt)>>1;
if(tr[cur].ls==0) tr[cur].ls=++tot,tr[tr[cur].ls].tag2=1,tr[tr[cur].ls].lt=tr[cur].lt,tr[tr[cur].ls].rt=mid;
if(tr[cur].rs==0) tr[cur].rs=++tot,tr[tr[cur].rs].tag2=1,tr[tr[cur].rs].lt=mid+1,tr[tr[cur].rs].rt=tr[cur].rt;
tr[tr[cur].ls].sum=(tr[tr[cur].ls].sum*tr[cur].tag2)%mod;
tr[tr[cur].rs].sum=(tr[tr[cur].rs].sum*tr[cur].tag2)%mod;
tr[tr[cur].ls].tag1=(tr[tr[cur].ls].tag1*tr[cur].tag2)%mod;
tr[tr[cur].rs].tag1=(tr[tr[cur].rs].tag1*tr[cur].tag2)%mod;
tr[tr[cur].ls].tag2=(tr[tr[cur].ls].tag2*tr[cur].tag2)%mod;
tr[tr[cur].rs].tag2=(tr[tr[cur].rs].tag2*tr[cur].tag2)%mod;
tr[cur].tag2=1;
}
}
void pushdown(int cur){
pushdown2(cur);
pushdown1(cur);
}
void update1(int &cur,int lt,int rt,int l,int r,int v){
if(lt>r||rt<l) return ;
if(cur==0){
cur=++tot;
tr[cur].lt=lt,tr[cur].rt=rt,tr[cur].tag2=1,tr[cur].tag1=0;
}
if(l<=lt&&rt<=r){
tr[cur].sum+=((v%mod)*(rt-lt+1)%mod);
tr[cur].sum%=mod;
tr[cur].tag1+=v;
tr[cur].tag1%=mod;
return ;
}
pushdown(cur);
int mid=(lt+rt)>>1;
update1(tr[cur].ls,lt,mid,l,r,v);
update1(tr[cur].rs,mid+1,rt,l,r,v);
pushup(cur);
}
void update2(int &cur,int lt,int rt,int l,int r,int v){
if(lt>r||rt<l) return ;
if(cur==0){
cur=++tot;
tr[cur].lt=lt,tr[cur].rt=rt,tr[cur].tag2=1,tr[cur].tag1=0;
}
if(l<=lt&&rt<=r){
tr[cur].sum*=v;
tr[cur].sum%=mod;
tr[cur].tag2*=v;
tr[cur].tag2%=mod;
tr[cur].tag1*=v;
tr[cur].tag1%=mod;
return ;
}
pushdown(cur);
int mid=(lt+rt)>>1;
update2(tr[cur].ls,lt,mid,l,r,v);
update2(tr[cur].rs,mid+1,rt,l,r,v);
pushup(cur);
}
int a[maxn],n;
signed main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
update1(rt,1,top,1,a[1],1);
for(int i=2;i<=n;i++){
int sum=tr[rt].sum%mod;
update2(rt,1,top,1,a[i],-1);
update1(rt,1,top,1,a[i],sum);
update2(rt,1,top,a[i]+1,top,0);
}
cout<<(tr[rt].sum+mod)%mod;
return 0;
}
CF1591F 题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- uniapp底层跨端原理
uniapp底层跨端原理 - 代码编写:开发者使用Vue.js框架编写uniapp的代码,包括页面结构.样式和逻辑等. - 编译过程:在编译过程中,uniapp会将Vue.js的代码转换为各个平台所需 ...
- 聊聊MySQL是如何处理排序的
本文分享自华为云社区<MySQL怎样处理排序️如何优化需要排序的查询?>,作者:菜菜的后端私房菜. 前言 在MySQL的查询中常常会用到 order by 和 group by 这两个关键 ...
- 守护安全|AIRIOT城市天然气综合管理解决方案
城市使用天然气存在安全风险和隐患,天然气管理的复杂性也比较高,依靠传统人工难以发现安全漏洞,特别是在燃气场站.管网的安全监管等方面,场站面临作业管理.区域管控等问题,管线存在第三方施工发现问题不及 ...
- 生物医学顶刊论文(JBHI-2024):TransFOL:药物相互作用中复杂关系推理的逻辑查询模型
(2024.5.17)JBHI-TransFOL:药物相互作用中复杂关系推理的逻辑查询模型 论文题目:TransFOL: A Logical Query Model for Complex Relat ...
- 1 - 香橙派硬件PWM控制sg90舵机
本人机械电子专业的大一学生一枚,这是我在博客园的第一篇随笔 2024年4月份我在二手平台花费300大洋入手了香橙派zero3和3B,买回来后一开始是装上ubuntu跑QQ机器人和minecraft ...
- Python的进程和线程——一些基础概念
1. 线程和进程 1.1 线程和进程 进程可以包含多个并行运行的线程: 通常,操作系统创建和管理线程比进程更省CPU资源: 线程用于一些小任务,进程用于繁重的任务: 同一个进程下的线程共享地址空间和其 ...
- 『手撕Vue-CLI』函数柯里化优化代码
开篇 在上一篇文章中,给 nue-cli 添加了拉取版本号的功能,这一次来优化一下代码,使用函数柯里化的方式来优化代码. 实现 函数柯里化 函数柯里化是一种将使用多个参数的一个函数转换成一系列使用一个 ...
- linux系统下,安装docker教程,以CentOS8为例
查看本机的系统信息: 使用命令 lsb_release -a ,可以看到本机是CentOS系统,版本是8.4.2105 一.安装docker 1.Docker的安装要求CentOS系统内核版本要高于3 ...
- Spring扩展———自定义bean组件注解
引言 Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制. Java 语言中的类.方法.变量.参数和包等都可以被标注.和 Javadoc 不同,Java ...
- mysql分组求最大ID记录行方法
##创建表 CREATE TABLE `test_user` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `order_no` BIGINT(20) DEFAULT ...