您的位置:首页 > 运维架构

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;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: