Nonsense Time【2019 HDU多校6】【动态维护最长上生子序列LIS】
2019-08-08 09:57
1251 查看
HDU-6635 题目链接
比赛的时候想的是存在一条链上,去判断是否在这条LIS链上,在就更新,不在就继续继承答案,然后就这样T掉了,因为我真的用了一条Dijkstra的链……
这里的时间复杂度为什么是O(N * sqrt(N) * log(N))呢,是因为这里给出的数都是随机的,并且在一个一个添加进来的数也是随机的,表示的是(出题人并没有出强数据),讲题解的人如是说到。
然后在这里,就是去维护是否在这条LIS链上即可,在就更新,不在就不更新,只是这里的Code写起来需要谨慎一点,我的线段树被卡掉了,然后就去写了树状数组来维护这个,然后注意维护的关系。
我维护的是树状数组上查最大的F(),然后存的是对应点的值。
[code]#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 #define INF 0x3f3f3f3f #define HalF (l + r)>>1 #define lsn rt<<1 #define rsn rt<<1|1 #define Lson lsn, l, mid #define Rson rsn, mid+1, r #define QL Lson, ql, qr #define QR Rson, ql, qr #define myself rt, l, r using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 5e4 + 7; int N, a[maxN], re[maxN], p[maxN], pre[maxN], nex[maxN], bit[maxN], F[maxN], out[maxN], las[maxN]; bool used[maxN]; inline void update(int x) { int cop = x; while(x <= N) { if(F[bit[x]] < F[cop]) bit[x] = cop; x += lowbit(x); } } inline int query(int x) { int ans = 0; while(x) { if(F[ans] < F[bit[x]]) ans = bit[x]; x -= lowbit(x); } return ans; } inline int ex_change() { int maxx = 0, id = 0; for(int i=nex[0], u; i<=N; i=nex[i]) { used[i] = false; u = query(a[i]); F[a[i]] = F[u] + 1; las[i] = re[u]; if(F[a[i]] > maxx) { maxx = F[a[i]]; id = i; } update(a[i]); } for(int i=1; i<=N; i++) bit[i] = F[i] = 0; for(int i=id; i; i=las[i]) used[i] = true; return maxx; } int main() { int Cas; scanf("%d", &Cas); while(Cas--) { scanf("%d", &N); for(int i=1; i<=N; i++) { scanf("%d", &a[i]); re[a[i]] = i; } for(int i=1; i<=N; i++) scanf("%d", &p[i]); for(int i=0; i<=N; i++) { pre[i] = i - 1; nex[i] = i + 1; } for(int i=1; i<=N; i++) { bit[i] = 0; used[i] = false; } int now = ex_change(); for(int i=N, pos; i>=1; i--) { pos = p[i]; out[i] = now; pre[nex[pos]] = pre[pos]; nex[pre[pos]] = nex[pos]; if(used[pos]) now = ex_change(); } for(int i=1; i<=N; i++) printf("%d%c", out[i], i == N ? '\n' : ' '); } return 0; }
相关文章推荐
- 2019 Multi-University Training Contest 6 1002 Nonsense Time —— 暴力LIS,记录最长上升子序列
- hdu 5125 二分nlogn求最长上升子序列(LIS)+dp
- 动态规划-最长递增序列(LIS)【模板】
- hdu 5421 小明系列问题——小明序列(LIS最长上升子序列)
- 【维护区间最长连续子序列 && 线段树 && 区间归并】HDU - 1540 Tunnel Warfare
- (HDU 5773)The All-purpose Zero <最长上升子序列 + 思维题> 多校训练4
- 动态规划实例(一):最长递增子序列(LIS)
- hdu 5324 Boring Class 2015多校联合训练赛3 分治,最长不降子序列,最小字典序
- 最长上升子序列(LIS)(HDU 1025)
- hdu 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列(LIS)O(nlogn)算法)
- 动态规划-最长递增序列(LIS)【模板】
- hdu----(1950)Bridging signals(最长递增子序列 (LIS) )
- HDU 5807(Revenge of LIS II)最长不降子序列
- hdu 1087 LIS 最长递增子序列的值
- [LIS_最长递增子序列]-hdu 1087 Super Jumping!
- hdu1160 FatMouse's Speed 最长上升子序列 LIS
- hdu 5256 序列变换(LIS最长上升子序列)
- 最长不下降子序列(动态规划:LIS)
- 动态规划——最长不下降子序列(LIS)
- hdu 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列(LIS)O(nlogn)算法)