[Luogu5156]

题解

求字典序第 k 小的满足题意的集合,取反一下,就是求序列中字典序第 k 大的最长上升子序列

[51nod1376] 最长递增子序列的数量

置 \(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(树状数组)的更多相关文章

  1. HDU 2689 Sort it【树状数组】

    Sort it Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  2. nyoj322 sort 归并排序,树状数组

    Sort 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 You want to processe a sequence of n distinct integers b ...

  3. Bubble Sort HDU - 5775 树状数组

    //每个数字只会被它后面的比它小的数字影响,且会向右移动相应个数的位置 //比如:6 4 3 5 2 1 .4后面比它小的有 三个,因此它的最右边位置就是当前位置 +3,即5 //如果该数字本身在标准 ...

  4. 2016 Multi-University Training Contest 4 Bubble Sort(树状数组模板)

    Bubble Sort 题意: 给你一个1~n的排列,问冒泡排序过程中,数字i(1<=i<=n)所到达的最左位置与最右位置的差值的绝对值是多少 题解: 数字i多能到达的最左位置为min(s ...

  5. hdu_5775_Bubble Sort(树状数组)

    题目链接:hdu_5775_Bubble Sort 题意: 让你找每一个数在冒泡排序中最右边和最左边的位置的差值 题解: 还是官方题解,讲的已经很清楚了 1012 Bubble Sort 考虑一个位置 ...

  6. hdu 5775 Bubble Sort 树状数组

    Bubble Sort 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5775 Description P is a permutation of t ...

  7. codeforces 652D D. Nested Segments(离散化+sort+树状数组)

    题目链接: D. Nested Segments time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  8. HDU 5775:Bubble Sort(树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=5775 Bubble Sort Problem Description   P is a permutation ...

  9. AtCoder Regular Contest 088 E - Papple Sort(树状数组+结论)

    结论:每次把字符丢到最外面最优,用树状数组统计答案,把字符放到最外边后可以当成消失了,直接在树状数组上删掉就好. 感性理解是把字符丢到中间会增加其他字符的移动次数,但是丢到外面不会,所以是正确的. # ...

随机推荐

  1. Shell编程实战 1.1 监控思路架构介绍

    监控思路,架构介绍 需求:使用shell定制各种个性化的告警工具,但需要统一化管理,规范化管理. 思路:指定一个脚本包,包含主程序,子程序,配置文件,邮件引擎,输出日志等. 主程序:作为脚本的入口,是 ...

  2. js分页demo

    纯js实现分页   原理:所有数据已加载好,js通过遍历部分显示,实现分页效果 html代码 <html> <head> <meta charset='utf-8'> ...

  3. java之静态函数和静态变量

    静态变量: 静态变量好似一种成员变量,它的特点是前面有static. 普通变量会有多份,它在每个对象当中都存在,但是静态变量只有一份,它是属于类的. 静态变量的调用方法: 1.类名.变量名 Custo ...

  4. python爬虫(1)--Urllib库的基本使用

    这里使用python2.7,pycharm进行代码编写 1.爬一个静态网页示例 import urllib2 response = urllib2.urlopen("http://www.b ...

  5. Android ScrollView 内部控件 layout_margin失效的解决方法

    在<ScrollView> 的<LinearLayout  >属性里面加入android:layout_gravity="top" <LinearLa ...

  6. 关于c#运算符的简单应用。。。

    按套路,先罗列一下各种运算符. 运算符的分类: 算数: +-*/(加减乘除)%(取余,就是除不尽剩下的,77/10就余7),++(加加)--(减减) 关系:>  <  >=  < ...

  7. p3163 [CQOI2014]危桥

    传送门 分析 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string ...

  8. Git 之 github分享代码

    作为一个技术人员还是脱离不了屌丝的本质,所以每天都是逛逛github,看看别人有什么好的项目,自己可以给他挑挑bug也可以提供自己的水平,但是别人不那怎么才能给别人贡献代码呢?那就是fork了.... ...

  9. 《Head First Servlets & JSP》-7-使用JSP

    学习的知识点 JSP,最后会变成一个servlet JSP最终或变成一个完整的servlet在Web应用中运行,只不过这个servlet类会由容器写好. JSP中的scriptlet 所谓script ...

  10. 《Maven实战》笔记-1-Maven使用入门

    <Maven实战>徐晓斌 2011 机械工业出版社   一.介绍 1.名词 artifact:插件 极限编程XP 2.构建脚本: maven——pom.xml(Project Object ...