hdu 6635 Nonsense Time 暴力求最长上升子序列LIS

题目要求在随机排序的数列中,根据给定的顺序显现元素,每次操作后计算最长上升子序列(LIS)的长度。通过时间倒流的视角,可以先在O(n log n)时间内找到原始的LIS,然后在删除每个数时判断其是否在原LIS中,若不在则LIS长度不变,否则暴力重新计算LIS。由于数据随机,LIS的期望长度为O(√n),因此平均期望时间复杂度为O(n√n log n)。
摘要由CSDN通过智能技术生成

题意:

       现在给你n个随机的成排序的数ai(注意是随机的!),现在他们都是隐藏的,然后再给你一个n的排序bi,每次你要依次把bi这个位置上的数依次显现,问你每次操作之后的最长上升序列数LIS是多少。

 

做法:

       考虑时间倒流,看作一个完整的排列按照一定顺序依次删除每个数,然后每次需要计算LIS 的长度。
       首先在 O(n log n) 的时间内求出 LIS,并找到一个 LIS。当删除 x 时,如果 x 不在之前找到的那个 LIS 中,那么显然 LIS 的长度是不会变化的,否则暴力重新计算出新的 LIS 即可。因为数据随机,因此 LIS 的期望长度是 O(√n),删除的 x 位于 LIS 中的概率是 √1n,也就是说期望删除 O(√n) 个数才会修改 LIS,那么 LIS 变化的次数不会很多。期望时间复杂度为 O(n√n log n)。

 

#include<bits/stdc++.h>
#define ll long long 
#define max 50005
using namespace std;

int a[max],b[max],vis[max];
int d[max],path[max],ans[max];
int us[max]; 
int n;
int solve(){
	int len=0;
	fill(d,d+max,0); 
	for(int i=0;i<n;i++){
		if(vis[i] == -1) continue;
		int it = lower_bound(d,d+len,a[i]) - d;
		if(it==l
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值