[解题报告] HDU 6635 Nonsense Time(多校 LIS 思维 暴力)

阅读: 评论:0

[解题报告] HDU 6635 Nonsense Time(多校 LIS 思维 暴力)

[解题报告] HDU 6635 Nonsense Time(多校 LIS 思维 暴力)

题目链接

题目大意

起初给你n的排列,然后给你一个序列b,b[i]表示第i轮位置为b[i]的数可用,问每一轮可用的数列形成的LIS(最长上升子序列)为多少。

LIS

推荐一篇特别详细特别用心的博客:
戳最长上升子序列 (LIS) 详解+例题模板 (全)
LIS的两种nlogn的方法都需要掌握,但是常用的是贪心+二分的这种,树状数组思想比写法重要,要善于灵活应用,特别是很类似于离散化然后添点形成大小关系从而求出某种序列的时候,要想到类比LIS的树状数组做法。

官方题解

考虑时间倒流,一开始先求出整个排列的LIS
然后考虑删点
如果删的点不在LIS中,那么我们当前轮次的LIS就是上一轮次的LIS
否则删的点在LIS中,那么我们就需要重新求一遍LIS,这里有点暴力的意思,但是由于数据随机生成,所以在LIS中的点大概有根号n个,所以其实不会超时
这里涉及到一个点是记录LIS的路径,代码中有所体现,可以当成板子背一下,其实和dp记录路径的思想是一样的,先求完然后倒推回来。
总时间复杂度 O(n * sqrt(n) * logn),14s的时间…

//#include <bits/stdc++.h>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <string>
#include <utility>
#include <assert.h>
#define endl 'n'
#define p_b push_back
#define e_b emplace_back
#define debug cout<<"!!!"<<endl;
//#define LOCAL
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
const static int inf = 0x3f3f3f3f;
const static ll infll = 0x3f3f3f3f3f3f3f3f;
const static int maxn = 5e4+10;int n;
int a[maxn], b[maxn];
bool froze[maxn];
bool used[maxn];
int res[maxn];
int path[maxn];
int li[maxn];int lis()
{memset(path, 0, sizeof path);int ret = 0;for(int i=1; i<=n; i++){if(froze[a[i]])continue;//这里尽量这样写,更合理一些,li数组是下标为0开始存放贪心得到的序列int pos = lower_bound(li, li+ret, a[i]) - li;if(pos == ret){li[ret++] = a[i];path[i] = ret;}else{path[i] = pos+1;//加1是下标偏移li[pos] = a[i];}}memset(used, false, sizeof used);int tmp = ret;for(int i=n; i>=1; i--){if(froze[a[i]])continue;if(path[i] == tmp){used[a[i]] =  true;tmp--;}}return ret;
}int main()
{#ifdef Localfreopen("1002.in", "r", stdin);freopen("1.out", "w", stdout);#endifint t;scanf("%d", &t);while(t--){memset(froze, false, sizeof froze);memset(res, 0, sizeof res);scanf("%d", &n);for(int i=1; i<=n; i++) scanf("%d", &a[i]);for(int i=1; i<=n; i++) scanf("%d", &b[i]);res[n] = lis();//cout<<res[n]<<endl;//debug;froze[a[b[n]]] = true;for(int i=n-1; i>=1; i--){if(!used[a[b[i+1]]])res[i] = res[i+1];elseres[i] = lis();froze[a[b[i]]] = true;}for(int i=1; i<=n; i++){if(i == 1)printf("%d", res[i]);elseprintf(" %d", res[i]);}printf("n");}return 0;
}

本文发布于:2024-01-31 16:20:44,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170668924729816.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:暴力   思维   报告   HDU   Time
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23