【bzoj4881】[Lydsy2017年5月月赛]线段游戏 树状数组+STL-set
题目描述
输入
输出
样例输入
5
1 2 4 5 3
样例输出
8
题目大意
给定一个1~n的全排列序列,求出将这个序列分成两个都不含逆序对的子序列的方案数(子序列可以为空,可以不连续)
题解
树状数组+STL-set
先说一下个人的思路吧~(按照这个思路T了,后面会讲优化)
首先,一个逆序对不能分在同一个子序列里,即一个逆序对必须分到两个不同的子序列里。
对于每个逆序对组(一个集合,其中每个元素都至少与一个其它元素存在逆序对关系),只存在两种不同的分法,所以可以用带权并查集来维护逆序对组数。
于是每次找到一个数,就看它前面有多少个比它大的数,然后将所有比它大的数与它在带权并查集中合并,若矛盾则无解,最后统计一下就可以了。
而这里如果加了无解判断,那么合并操作的总次数是O(n)级别的。
然而一开始用set TLE了,才发现set很难查询一段区间,时间会很长。
所以要手写Treap或Splay,果断放弃。
最后还是参考了下 CQzhangyu 大犇的做法:先用树状数组求最长下降子序列,判断是否达到3导致无解;然后插入时只保留它和比它大的数中的最大的那个,最后答案为2^size。
这里简单证明一下:按照我的做法,每次带权并查集合并时都要合并很多数,而实际上如果有解,那么只需要保留一个逆序对组的一个元素即可代表整个组。由于是逆序对,这个元素最大时才能代表整个组来继续进行接下来的元素的合并操作。
所以不需要每次都找所有比当前数大的,只需要维护最大值就行了。
#include <cstdio>
#include <set>
#define N 100010
using namespace std;
int n , f[N] , a[N];
set<int> s;
set<int>::iterator it;
void update(int x , int a)
{
int i;
for(i = x ; i <= n ; i += i & -i) f[i] = max(f[i] , a);
}
int query(int x)
{
int i , ans = 0;
for(i = x ; i ; i -= i & -i) ans = max(ans , f[i]);
return ans;
}
int main()
{
int i , tmp , ans = 1;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%d" , &a[i]);
tmp = query(n - a[i]);
if(tmp >= 2)
{
printf("0\n");
return 0;
}
update(n - a[i] + 1 , tmp + 1);
}
for(i = 1 ; i <= n ; i ++ )
{
tmp = a[i];
while((it = s.upper_bound(tmp)) != s.end()) tmp = *it , s.erase(tmp);
s.insert(tmp);
}
tmp = s.size();
while(tmp -- ) ans = ans * 2 % 998244353;
printf("%d\n" , ans);
return 0;
}
【bzoj4881】[Lydsy2017年5月月赛]线段游戏 树状数组+STL-set的更多相关文章
- [bzoj4881][Lydsy2017年5月月赛]线段游戏
来自FallDream的博客,未经允许,请勿转载,谢谢. quailty和tangjz正在玩一个关于线段的游戏.在平面上有n条线段,编号依次为1到n.其中第i条线段的两端点坐标分别为(0,i)和(1, ...
- BZOJ 4881: [Lydsy2017年5月月赛]线段游戏
4881: [Lydsy2017年5月月赛]线段游戏 Time Limit: 3 Sec Memory Limit: 256 MBSubmit: 164 Solved: 81[Submit][St ...
- 【BZOJ4881】5月月赛D 线段游戏 树状数组+set
Description quailty和tangjz正在玩一个关于线段的游戏.在平面上有n条线段,编号依次为1到n.其中第i条线段的两端点坐 标分别为(0,i)和(1,p_i),其中p_1,p_2,. ...
- BZOJ4881: [Lydsy1705月赛]线段游戏(二分图)
4881: [Lydsy1705月赛]线段游戏 Time Limit: 3 Sec Memory Limit: 256 MBSubmit: 359 Solved: 205[Submit][Stat ...
- [补档][Lydsy2017年4月月赛]抵制克苏恩
[Lydsy2017年4月月赛]抵制克苏恩 题目 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平. 如果你不玩炉石传说,不必担心,小Q同学会告诉你所有相关的细节.炉石传说是这样的一 ...
- 【BZOJ 4832 】 4832: [Lydsy2017年4月月赛]抵制克苏恩 (期望DP)
4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 275 Solved: 87 Descripti ...
- 【BZOJ4832】[Lydsy2017年4月月赛]抵制克苏恩 概率与期望
[BZOJ4832][Lydsy2017年4月月赛]抵制克苏恩 Description 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q同学会告诉 ...
- [Bzoj4832][Lydsy2017年4月月赛]抵制克苏恩 (期望dp)
4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 673 Solved: 261[Submit][ ...
- bzoj 4836: [Lydsy2017年4月月赛]二元运算 -- 分治+FFT
4836: [Lydsy2017年4月月赛]二元运算 Time Limit: 8 Sec Memory Limit: 128 MB Description 定义二元运算 opt 满足 现在给定一 ...
随机推荐
- 4、SpringBoot------邮件发送(2)
开发工具:STS 代码下载链接:https://github.com/theIndoorTrain/Springboot/tree/0d6194d6ea2d7f4e19791a3d3f3167f861 ...
- Spring 中IOC(控制反转)&& 通过SET方式为属性注入值 && Spring表达式
### 1. Spring IoC IoC:Inversion of control:控制反转:在传统开发模式下,对象的创建过程和管理过程都是由开发者通过Java程序来实现的,操作权在开发者的Java ...
- IDEA 编辑框光标闪烁
依次打开如下菜单: File -> Settings -> Editor -> General -> Appearance -> 选中 Caret blinking (m ...
- VS2013未能正确加载的问题【转载】
今天使用电脑,关机重启时,WINDOWS提示“正在配置中,请勿关机” 的提醒,等重启后,打开VS2013就提示了未加载成功的问题,如下图: 我的解决方法是:找到VS2013开发人员命令提示:在窗口中输 ...
- C++ Primer 学习笔记_Chapter4 数组和指针–指针
一.什么是指针? 指针与迭代器一样,指针提供对其所指对象的间接访问,指针保存的是另一个对象的地址: string s("hello"); string *ps = &s; ...
- POJ 3171 区间最小花费覆盖 (DP+线段树
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4245 Accepted: 1429 D ...
- 012---Django的用户认证组件
知识预览 用户认证 回到顶部 用户认证 auth模块 ? 1 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的 ...
- 零基础学html第一天
html:超文本标记语言 unicode(UTF-8):万国码 <...>:标记标签 :空格 <br>:换行 <hr>:水平线 <p></p& ...
- 初见akka-02:rpc框架
1.RPC:简单点说,就是多线程之间的通信,我们今天用了scala以及akka 来简单的实现了 rpc框架的一些简单的内容,一脸包括了,心跳,间隔时间, 注册以及一些问题, 模式匹配的一些东西,虽然比 ...
- 8 定制10MINs 3
1. <div class="ui inverted red basic segment"> <h3 class="ui header"> ...