【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 满足 现在给定一 ...
随机推荐
- 3、SpringBoot+MybatisPlus整合-------代码生成器
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</art ...
- typeid操作符
typeid() operator返回type_info,返回值不可拷贝.不可赋值 // Illustrates the typeid operator. #include <iostream& ...
- Swift小记一
1.输出地址 print(String(format: "%p", "temp")) 2.判断字符串是否为空串.是否为nil 为String添加一个分类 ext ...
- POJ2409 Let it Bead(Polya定理)
Let it Bead Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6443 Accepted: 4315 Descr ...
- LeetCode-177:第N高的薪水
第N高的薪水与第二高的薪水,解题思路是一样的,只要对LeetCode-176的SQL做一下变形,便可以满足这题,详见:https://www.cnblogs.com/zouqf/p/10282392. ...
- 交换机基础设置之vtp管理vlan设置
vtp的设置有三种模式1:server模式,负责创建,删除vlan(服务器模式) 2:client模式,负责接收并转发来自server的信息(客户机模式) 3:transparent模式,只负责转发, ...
- form表单submit按钮提交页面不跳转
方案一 <html> <body> <form action="" method="post" target="nm_i ...
- python--Pandas(一)
一.Pandas简介 1.Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的.Pandas 纳入了大量库和一 ...
- 【PHP】Maximum execution time of 30 seconds exceeded解决办法
Maximum execution time of 30 seconds exceeded,今天把这个错误的解决方案总结一下: 简单总结一下解决办法: 报错一:内存超限,具体报错语句忘了,简单说一下解 ...
- 【Sklearn系列】使用Sklearn进行数据预处理
这篇文章主要讲解使用Sklearn进行数据预处理,我们使用Kaggle中泰坦尼克号事件的数据作为样本. 读取数据并创建数据表格,查看数据相关信息 import pandas as pd import ...