[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 查看一个端口的连接数
netstat -antp|grep -i "80" |wc -l 譬如查看80端口的连接数
- Codeforces 1093E Intersection of Permutations (CDQ分治+树状数组)
题意:给你两个数组a和b,a,b都是一个n的全排列:有两种操作:一种是询问区间在数组a的区间[l1,r1]和数组b的区间[l2,r2]出现了多少相同的数字,另一种是交换数组b中x位置和y位置的数字. ...
- koa1链接mongodb
1.项目下安装mongodb和mongoose npm install mongodb --save-dev npm install mongoose --save-dev 2.router中 var ...
- 项目一:第十四天 1.在realm中动态授权 2.Shiro整合ehcache 缓存realm中授权信息 3.动态展示菜单数据 4.Quartz定时任务调度框架—Spring整合javamail发送邮件 5.基于poi实现分区导出
1 Shiro整合ehCache缓存授权信息 当需要进行权限校验时候:四种方式url拦截.注解.页面标签.代码级别,当需要验证权限会调用realm中的授权方法 Shiro框架内部整合好缓存管理器, ...
- 使用bat一键打开java、jar、py文件
直接运行jar是没有命令行窗口的,如果想有命令行窗口,一般来说是要 win+r 运行cmd,定位到所在目录,然后用命令行执行 java -jar xxx.jar 而对于python,打开py文件也是麻 ...
- [学习笔记]scanf弊端以及解决方案
#include<stdio.h> #include<stdlib.h> #include<unistd.h> int main(void) { ]; //mems ...
- Windows7 安装TensorFlow(本人试了好多方法后的成果)
本人机器为64位win7 首先安装python,版本一定要注意,TennsorFlow要使用 Python3.0 系列版本不能使用2.0系列版本,但是TensorFlow 的安装包目前windows版 ...
- 基于jQuery的Tooltip
近来,要开发一个关务管理系统,为了增加系统美观度,自己开发了一个基于jQuery框的的小插件,与大家分享一下,希望大家能给我提出宝贵修改意见. 下面开发说明使用方法和内容: 一.引用jQuery框架, ...
- 2019年第十届蓝桥杯省赛总结(JavaA组)
//update3.28:省一rank4,莫名进了国赛好神奇.. 记yzm10第一次体验A组(纯粹瞎水). 早闻山东的JavaA组神仙打架,进国赛都成了奢望(往年只有五个名额),因此抱着做分母的心态来 ...
- 后台调js方法
Page.ClientScript.RegisterStartupScript(Page.GetType(), "", "<script>btnSearch( ...