Description

quailty和tangjz正在玩一个关于线段的游戏。在平面上有n条线段,编号依次为1到n。其中第i条线段的两端点坐
标分别为(0,i)和(1,p_i),其中p_1,p_2,...,p_n构成了1到n的一个排列。quailty先手,他可以选择一些互不相交
的线段,将它们拿走,当然他也可以一条线段也不选。然后tangjz必须拿走所有剩下的线段,若有两条线段相交,
那么他就输了,否则他就赢了。注意若quailty拿走了全部线段,那么tangjz也会胜利。quailty深深喜欢着tangjz
,所以他不希望tangjz输掉游戏,请计算他有多少种选择线段的方式,使得tangjz可以赢得游戏。

Input

第一行包含一个正整数n(1<=n<=100000),表示线段的个数。
第二行包含n个正整数p_1,p_2,...,p_n(1<=p_i<=n),含义如题面所述。

Output

输出一行一个整数,即tangjz胜利的方案数,因为答案很大,请对998244353取模输出。

问题可以转化为:
给定一个序列,求将这个序列分成两个上升子序列的方案数.
令 $f_{i,j}$ 表示一个序列选 $i$,令一个序列的最大值为 $p_{j}$ 的方案数 ($j<i$).
考虑转移:

  • $f_{i,j}=f_{i-1,j},j<i-1$ 且 $p_{i-1}<p_{i}$
  • $f_{i,i-1}=\sum f_{i-1,k},p_{k}<p_{i}$

$f_{i,j}$ 的转移只和 $f_{i-1,?}$ 的转移有关,所以可以将第一维滚掉.
而每一次 $f$ 的更新只有两种:区间清零,用一个区间和来更新单点的点值.
这些操作可以用线段树来实现.

#include <cstdio>
#include <algorithm>
#define N 100006
#define mod 998244353
#define setIO(s) freopen(s".in", "r" , stdin)
using namespace std;
int a[N], n ;
struct Node
{
int sum, lazy ;
}t[N << 2];
inline void mark(int now)
{
t[now].sum = 0, t[now].lazy = 1;
}
inline void pushdown(int l, int r, int now)
{
int mid = (l + r) >> 1;
if(t[now].lazy)
{
mark(now << 1);
if(r > mid) mark(now << 1 | 1);
t[now].lazy = 0;
}
}
inline void pushup(int l, int r, int now)
{
int mid = (l + r) >> 1;
t[now].sum = t[now << 1].sum ;
if(r > mid) t[now].sum += t[now << 1 | 1].sum, t[now].sum %= mod ;
}
inline void update(int l, int r, int now, int p, int v)
{
if(l == r)
{
t[now].sum += v, t[now].sum %= mod;
return ;
}
int mid = (l + r) >> 1;
pushdown(l, r, now);
if(p <= mid) update(l, mid, now << 1, p, v);
else update(mid + 1, r, now << 1 | 1, p, v);
pushup(l, r, now);
}
inline int query(int l, int r, int now, int L, int R)
{
if(l >= L && r <= R) return t[now].sum ;
pushdown(l, r, now);
int mid = (l + r) >> 1, re = 0;
if(L <= mid) re += query(l, mid, now << 1, L, R);
if(R > mid) re += query(mid + 1, r, now << 1 | 1, L, R);
return re % mod;
}
int main()
{
// setIO("input");
int i , j ;
scanf("%d", &n);
for(i = 1 ; i <= n ; ++ i) scanf("%d", &a[i]);
update(0, n, 1, 0, 1);
for(i = 2 ; i <= n ; ++ i)
{
int sum = query(0, n , 1, 0, a[i] - 1);
if(a[i] < a[i - 1]) mark(1);
update(0, n, 1, a[i - 1], sum);
}
printf("%d\n", query(0, n, 1, 0, n) * 2 % mod);
return 0;
}

  

BZOJ 4881: [Lydsy1705月赛]线段游戏 动态规划 + 线段树的更多相关文章

  1. bzoj 4881 [Lydsy1705月赛]线段游戏

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4881 1.当一块相互交织的线段中有3个或以上两两相交的那种线段时,无解. 这就是最长下降子序 ...

  2. bzoj 4880 [Lydsy1705月赛]排名的战争 贪心

    [Lydsy1705月赛]排名的战争 Time Limit: 8 Sec  Memory Limit: 256 MBSubmit: 338  Solved: 69[Submit][Status][Di ...

  3. 「雅礼集训 2017 Day2」线段游戏(线段树懒标记“启发式下传”,李超树)

    题面 题解 加入一条线段,可以把它转化为在[L,R]区间内加一条线 y=ax+b (如果原线段与y轴平行,就相当于在{x1}处加一条线 y=max(y1,y2)) 我们可以把它加到线段树上,线段树上每 ...

  4. BZOJ4881 线段游戏(二分图+树状数组/动态规划+线段树)

    相当于将线段划分成两个集合使集合内线段不相交,并且可以发现线段相交等价于逆序对.也即要将原序列划分成两个单增序列.由dilworth定理,如果存在长度>=3的单减子序列,无解,可以先判掉. 这个 ...

  5. bzoj 2017 [Usaco2009 Nov]硬币游戏 动态规划

    [Usaco2009 Nov]硬币游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 431  Solved: 240[Submit][Status] ...

  6. bzoj 4883 [Lydsy1705月赛]棋盘上的守卫——并查集(思路!)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4883 把各行和各列看成n+m个点. 如果一下能防守行和列,就是最大匹配了.这是每两个左右部点 ...

  7. BZOJ 4883: [Lydsy1705月赛]棋盘上的守卫 最小生成树 + 建模

    Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须恰好放置一个纵向守卫.每个位置放置守卫的代价是不一样的,且每个位置 ...

  8. BZOJ 5129: [Lydsy1712月赛]树上传送 点分树+Dijkstra

    Description http://www.lydsy.com/JudgeOnline/upload/201712/prob12.pdf Input Output 暑假集训的时候点分树做的比较少,所 ...

  9. BZOJ4881: [Lydsy1705月赛]线段游戏(二分图)

    4881: [Lydsy1705月赛]线段游戏 Time Limit: 3 Sec  Memory Limit: 256 MBSubmit: 359  Solved: 205[Submit][Stat ...

随机推荐

  1. websocket服务器推送 (node+express+vue+socket)

    简介: 此项目需要懂一点node.express 功能: 1.前端用户登录,查看服务端推送的消息,用户只能在一个地方登录,也就是单点登录 2.服务端首先登录,上传需要推送的信息文本,后台读取文本后,存 ...

  2. Maven使用基础

    (转)https://my.oschina.net/xiaomaoandhong/blog/104045 基于 约定优于配置(Convention Over Configuration)的原则,无特殊 ...

  3. BATJ的常见java面试题

    JAVA基础 JAVA中的几种基本数据类型是什么,各自占用多少字节. String类能被继承吗,为什么. 不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允 ...

  4. HDU-4507-吉哥系列故事-恨7不成妻

    题目描述 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: 2+1+4=7 7+7=7*2 ...

  5. centos7 下网卡的配置

    一般通过修改配置文件的方式去修改: 网卡配置文件位置    /etc/sysconfig/network-scripts/ifcfg-ens33 DNS配置文件位置              /etc ...

  6. 国际化:node导语言包

    项目做国际化,是离不开语言包的en.json.zh-CN.json等等.难道要一个一个json文件的写吗???不!!!只要我们写在excel里,然后用nodejs导出我们需要的语言包就可以了!这样大大 ...

  7. 在ubuntu上使用Openresty+lua实现WAF----折腾笔记

    1.1 参考loveshell的waf实现思路,再此感谢下面其中一部分是转载 1.2 WAF的功能 支持IP白名单和黑名单功能,直接将黑名单的IP访问拒绝.支持URL白名单,将不需要过滤的URL进行定 ...

  8. JavaScript中实现li向上轮播

    在网上找了很久,没有找到合适的模板,其实我这个也是公司用的,希望以后也能复用,节省时间 function scrollAuto(scrollBox, list){//两个参数分别填列表的ul的clas ...

  9. initdb - 创建一个新的 PostgreSQL数据库集群

    SYNOPSIS initdb [ option...] --pgdata | -D directory DESCRIPTION 描述 initdb 创建一个新的 PostgreSQL 数据库集群. ...

  10. [转载]【转】乘法器的Verilog HDL实现

      乘法器如果直接用*来实现的话,会消耗很多的资源.所以有了串行和并行两种实现思路.用串行的话,8位一般会有8位以上的延迟,但是消耗的资源是最少的.低速数据处理比较适合.并行也就是流水线方法,以时间换 ...