[USACO18DEC]Sort It Out(树状数组)
求字典序第 k 小的满足题意的集合,取反一下,就是求序列中字典序第 k 大的最长上升子序列
置 \(f_{i}\)表示以权值为 i 结尾的 LIS 的长度和数量,则权值 x 从 $ f_{1} \dots f_{x-1}$ 间转移,用树状数组维护前缀最大值和数量即可$ O(nlog n)$解决
假设当前要求的序列的 LIS 长度为 t ,则求第 k 大 LIS 的一个思想就是先确定第 1 个数,再在确定第 1 个数的基础上确定下一个数……以此类推可以最终确定 LIS 的每一位
细化一下,就是将所有可能作为 LIS 的第 i 位的数 放进第 i 个vector里,将每个vector内部进行元素排序,在确定每一位时从大到小确定,若当前值后面牵扯的 LIS 数量小于 k ,则将 k 减去这个数量然后检查下一个值,否则将这个值确定下来并开始确认下一位 , 也可以用链式前向星的方法实现
(值得注意的一点,若求 LIS 第 i 层选定了位置 R 的元素,则接下来都不能选择 R 左边的元素)
代码十分巧妙,值得学习
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
}
const int MAXN=1e5+5;
const LL limit=1e18;
struct Node{
int len;LL x;
inline friend void operator += (Node &A,Node B){
if(B.len>A.len) A.len=B.len,A.x=B.x;
else if(B.len==A.len) A.x=min(A.x+B.x,limit);
}//树状数组维护最大长度和方案数
}f[MAXN];
int n;LL K;
struct BIT{
Node a[MAXN];
inline void insert(int x,Node y){
for(;x;x-=x&-x) a[x]+=y;
}
inline Node query(int x){
Node res=(Node){0,0};
for(;x<=n+1;x+=x&-x) res+=a[x];
return res;
}
}T;
struct Edge{
int v,next;
}e[MAXN];
int first[MAXN],Ecnt;
inline void Add_edge(int u,int v){
e[++Ecnt]=(Edge){v,first[u]};
first[u]=Ecnt;
}
int num[MAXN];
bool choose[MAXN];
signed main(){
n=read(),K=read();
T.insert(n+1,(Node){0,1});//按题意模拟上升序列
for(int i=1;i<=n;i++) num[i]=read();
for(int i=n;i>=1;i--){
f[i]=T.query(num[i]);//num[i]是个排列
f[i].len++;
T.insert(num[i],f[i]);
}
for(int i=n;i>=1;i--)
Add_edge(f[i].len,i);
for(int now=T.query(1).len,R=1;now;now--)
for(int i=first[now];i;i=e[i].next){//从右往左加边,从左往右遍历
int v=e[i].v;
if(K>f[v].x) K-=f[v].x;//找到第K大上升序列
else{
choose[num[v]]=true;
while(R<v) f[R++]=(Node){0,0};//选了这个数,在它左边的都不能选
break;//到剩下的下一层去再找第K大
}
}
printf("%d\n",n-T.query(1).len);
for(int i=1;i<=n;i++){
if(!choose[i]) printf("%d\n",i);//没被选中的,就是第K小的排列
}
}
[USACO18DEC]Sort It Out(树状数组)的更多相关文章
- HDU 2689 Sort it【树状数组】
Sort it Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- nyoj322 sort 归并排序,树状数组
Sort 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 You want to processe a sequence of n distinct integers b ...
- Bubble Sort HDU - 5775 树状数组
//每个数字只会被它后面的比它小的数字影响,且会向右移动相应个数的位置 //比如:6 4 3 5 2 1 .4后面比它小的有 三个,因此它的最右边位置就是当前位置 +3,即5 //如果该数字本身在标准 ...
- 2016 Multi-University Training Contest 4 Bubble Sort(树状数组模板)
Bubble Sort 题意: 给你一个1~n的排列,问冒泡排序过程中,数字i(1<=i<=n)所到达的最左位置与最右位置的差值的绝对值是多少 题解: 数字i多能到达的最左位置为min(s ...
- hdu_5775_Bubble Sort(树状数组)
题目链接:hdu_5775_Bubble Sort 题意: 让你找每一个数在冒泡排序中最右边和最左边的位置的差值 题解: 还是官方题解,讲的已经很清楚了 1012 Bubble Sort 考虑一个位置 ...
- hdu 5775 Bubble Sort 树状数组
Bubble Sort 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5775 Description P is a permutation of t ...
- codeforces 652D D. Nested Segments(离散化+sort+树状数组)
题目链接: D. Nested Segments time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- HDU 5775:Bubble Sort(树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=5775 Bubble Sort Problem Description P is a permutation ...
- AtCoder Regular Contest 088 E - Papple Sort(树状数组+结论)
结论:每次把字符丢到最外面最优,用树状数组统计答案,把字符放到最外边后可以当成消失了,直接在树状数组上删掉就好. 感性理解是把字符丢到中间会增加其他字符的移动次数,但是丢到外面不会,所以是正确的. # ...
随机推荐
- linux命令-fdisk分区
fdisk -l 查看分区状况,也可查看指定分区 Disk /dev/sda: 21.5 GB, 21474836480 bytes 255 heads, 63 sectors/track, 26 ...
- JDBC批处理数据
JDBC3.0 的增强支持BLOB,CLOB,ARRAY,REF数据类型.的ResultSet对象UPDATEBLOB(),updateCLOB(),updateArray()和updateRef( ...
- mysql工具Navicat批量执行SQL语句
例如:我现在要同时执行这么多语句 update community set xqmc=replace(xqmc,' ',''); update community set xqbm=replace(x ...
- 人工智能一之TensorFlow环境配置
1.安装pip:sudo apt-get install python-pip python-dev 2.定义仅支持CPU的python2.7环境下TensorFlow安装包地址:export TF_ ...
- Composite模式 组合模式
Android的ViewGroup 和 View 的关系,即是采用组合模式 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件 ...
- setAttribute这个方法
setAttribute这个方法,在JSP内置对象session和request都有这个方法,这个方法作用就是保存数据,然后还可以用getAttribute方法来取出.比如现在又个User对象,Use ...
- solr的查询语法、查询参数、检索运算符
转载自:http://martin3000.iteye.com/blog/1328931 1.查询语法 solr的一些查询语法 1.1. 首先假设我的数据里fields有:name, tel, add ...
- day17 10.jdbc的crud操作
每次都是注册驱动,获取连接,然后执行.每次都写很累,肯定能抽取出来一些东西.Java里面是这样的,相同的东西可以抽取做成一个方法.用的时候调这方法就OK了.这方法抽取到什么程度呢? package c ...
- 【安装关键】webStorm-201703版本
在激活页面选择License Server,输入:http://idea.codebeta.cn,点击Activate即可激活.
- springMVC 返回json乱码问题
多次遇见过这个问题,springMVC下返回给前端的json字符串,中文总是乱码,每次都要去翻一下之前的代码来看解决办法,有必要做个笔记记一下这个问题了. 解决方法: 在方法注解中加入如下: @Req ...