[atAGC052D]Equal LIS
令$f_{i}$表示以$i$为结尾的最长上升子序列,显然可以快速预处理
令$L=\max_{i=1}^{n}f_{i}$,当$L$为偶数,考虑如下构造——
将所有$f_{i}\le \frac{L}{2}$的$a_{i}$选入第1个序列,其余位置选入第2个序列
此时,来证明两个序列的最长上升子序列都是$\frac{L}{2}$
考虑这个长为$L$的最长上升子序列,其前$\frac{L}{2}$个元素必然都在第1个序列中,后$\frac{L}{2}$个元素必然都在第2个序列中,即两者最长上升子序列长度都大于等于$\frac{L}{2}$
另一方面,第1个序列中以$i$为结尾的最长上升序列小于等于$\frac{L}{2}$,第2个序列中以$i$为起点的最长上升序列小于等于$\frac{L}{2}$(由于$f_{i}>\frac{L}{2}$,且两者之和小于等于$L$,即有此结论),也都小于等于$\frac{L}{2}$
(其中$i$为各自序列中任意元素)
当$L$为奇数,假设$L=2k+1$,那么对于其中一个长为$L$的上升子序列,要存在一个元素$x$,其不在此序列中,且存在一个长为$k+1$的上升子序列包含其
关于这件事情的必要性是显然的,同时其也是充分的,考虑如下构造——
任选一个长为$L$的上升子序列,根据此性质,选择$x$并假设这个$k+1$的上升子序列为$p_{1},p_{2},...,p_{k+1}$
将所有满足$\forall 1\le j\le k+1,f_{i}\ne f_{p_{j}}$或$f_{i}=f_{x}$且$i\ne x$的$a_{i}$选入第1个序列,其余位置选入第2个序列
在第1个序列中,考虑这个长为$L$的上升子序列,设其中第$i$个位置为$x$,即有$f_{x}=i$,恰好包含$[1,L]$中所有值,其中恰有$k$个值不能选($f_{i}=f_{x}$是可以选的),构成一个长为$k+1$的上升子序列
在第2个序列中,$p_{i}$都被选入第2个序列,也构成一个长为$k+1$个上升子序列
另一方面,对于一个长为$k$的上升子序列,每一个位置的$f_{x}$必然各不相同,而注意到两个序列中都至多含有$k+1$个不同的$f$,即不存在长为$k+2$的上升子序列
关于判定,求出以每一个元素为起点和终点的最长上升子序列,即可求出强制包含某个元素的最长上升子序列,判定其是否大于等于$k+1$即可
由此,即解决此问题,时间复杂度为$o(n\log n)$


- 1 #include<bits/stdc++.h>
- 2 using namespace std;
- 3 #define N 200005
- 4 #define L (k<<1)
- 5 #define R (L+1)
- 6 #define mid (l+r>>1)
- 7 int t,n,ans,a[N],vis[N],f[N],g[N],mx[N<<2];
- 8 void build(int k,int l,int r){
- 9 mx[k]=0;
- 10 if (l==r)return;
- 11 build(L,l,mid);
- 12 build(R,mid+1,r);
- 13 }
- 14 void update(int k,int l,int r,int x,int y){
- 15 if (l==r){
- 16 mx[k]=y;
- 17 return;
- 18 }
- 19 if (x<=mid)update(L,l,mid,x,y);
- 20 else update(R,mid+1,r,x,y);
- 21 mx[k]=max(mx[L],mx[R]);
- 22 }
- 23 int query(int k,int l,int r,int x,int y){
- 24 if ((l>y)||(x>r))return 0;
- 25 if ((x<=l)&&(r<=y))return mx[k];
- 26 return max(query(L,l,mid,x,y),query(R,mid+1,r,x,y));
- 27 }
- 28 int main(){
- 29 scanf("%d",&t);
- 30 while (t--){
- 31 scanf("%d",&n);
- 32 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
- 33 ans=0;
- 34 build(1,1,n);
- 35 for(int i=1;i<=n;i++){
- 36 f[i]=query(1,1,n,1,a[i]-1)+1;
- 37 update(1,1,n,a[i],f[i]);
- 38 ans=max(ans,f[i]);
- 39 }
- 40 if (ans%2==0)printf("YES\n");
- 41 else{
- 42 build(1,1,n);
- 43 for(int i=n;i;i--){
- 44 g[i]=query(1,1,n,a[i]+1,n)+1;
- 45 update(1,1,n,a[i],g[i]);
- 46 }
- 47 bool flag=0;
- 48 for(int i=n,j=ans;i;i--)
- 49 if (f[i]==j)j--;
- 50 else{
- 51 if (f[i]+g[i]-1>=ans/2+1){
- 52 printf("YES\n");
- 53 flag=1;
- 54 break;
- 55 }
- 56 }
- 57 if (!flag)printf("NO\n");
- 58 }
- 59 }
- 60 }
[atAGC052D]Equal LIS的更多相关文章
- Codeforces Round #371 (Div. 2)E. Sonya and Problem Wihtout a Legend[DP 离散化 LIS相关]
E. Sonya and Problem Wihtout a Legend time limit per test 5 seconds memory limit per test 256 megaby ...
- 【HDU 4352】 XHXJ's LIS (数位DP+状态压缩+LIS)
XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 1053. Path of Equal Weight (30)
Given a non-empty tree with root R, and with weight Wi assigned to each tree node Ti. The weight of ...
- XHXJ's LIS(数位DP)
XHXJ's LIS http://acm.hdu.edu.cn/showproblem.php?pid=4352 Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 4352 - XHXJ's LIS - [数位DP][LIS问题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4352 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- hdu 4352 XHXJ's LIS 数位dp+状态压缩
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4352 XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others ...
- POJ 1836-Alignment(DP/LIS变形)
Alignment Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 13465 Accepted: 4336 Descri ...
- poj 1836 LIS变形
题目链接http://poj.org/problem?id=1836 Alignment Time Limit: 1000MS Memory Limit: 30000K Total Submiss ...
- CodeForces - 650D:Zip-line (LIS & DP)
Vasya has decided to build a zip-line on trees of a nearby forest. He wants the line to be as long a ...
随机推荐
- Android应用开发特色
目录 Android应用开发特色 四大组件 Activity Service Broadcastreceiver Contentprovider 丰富的系统控件 Sqlite数据库 强大的多媒体 An ...
- mybatis 操作数据库(05)
类型转换.动态排序,查询接口与mapper对应关系说明及其注意事项 一.MyBatis 自带写常见类型转换器.例如:java 类中 String 对应 mySQL中的varchar 二.自定义类型转换 ...
- Poetry(2)Poetry的基本使用方式
Poetry的基本使用 准备工作 如果你是在一个已有的项目里使用Poetry,你只需要执行 poetry init 命令来创建一个 pyproject.toml 文件: poetry init 可看到 ...
- 【Spring】IoC容器 - Spring Bean作用域Scope(含SpringCloud中的RefreshScope )
前言 上一章学习了[依赖来源],本章主要讨论SpringBean的作用域,我们这里讨论的Bean的作用域,很大程度都是默认只讨论依赖来源为[Spring BeanDefinition]的作用域,因为在 ...
- 【c++ Prime 学习笔记】第6章 函数
6.1 函数基础 函数定义包括:返回类型.函数名字.由0个或多个形参组成的列表以及函数体 通过调用运算符()来执行函数,它作用于一个表达式,该表达式是函数或函数指针.圆括号内是一个逗号隔开的实参列表, ...
- [技术博客]大闸蟹的技术博客,通过gitlab api进行用户批量创建
技术博客--通过gitlab api批量注册用户 gitlab登录界面本身提供了register功能,但需要手工一个个添加,对于一次性会添加整个班级的学生的软工平台来说并不科学合理.使用gitlab ...
- 微信小程序的实现原理
一.背景 网页开发,渲染线程和脚本是互斥的,这也是为什么长时间的脚本运行可能会导致页面失去响应的原因,本质就是我们常说的 JS 是单线程的 而在小程序中,选择了 Hybrid 的渲染方式,将视图层和逻 ...
- USART 硬件流控
流控的概念源于 RS232 这个标准,在 RS232 标准里面包含了串口.流控的定义.大家一定了解,RS232 中的"RS"是Recommend Standard 的缩写,即&qu ...
- 零基础入门C语言超详细的字符串详解
本篇文章是对C语言字符串操作进行了详细的总结分析,需要的朋友参考下 1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, ...
- 第01课 OpenGL窗口(2)
下一段包括了所有的绘图代码.任何您所想在屏幕上显示的东东都将在此段代码中出现.以后的每个教程中我都会在例程的此处增加新的代码.如果您对OpenGL已经有所了解的话,您可以在 glLoadIdentit ...