【HDOJ6635】Nonsense Time(时间倒流,lis)

时间:2023-03-09 14:19:01
【HDOJ6635】Nonsense Time(时间倒流,lis)

题意:给定n个数的数列,第i个数为a[i],刚开始所有位置都处于禁用状态,第i次之后位置p[i]变为可用,求每次变化后的lis长度

n,a[i],p[i]<=5e4

保证a[i],p[i]均为随机生成的排列

思路:不知道非随机版本能不能树套树解决

【HDOJ6635】Nonsense Time(时间倒流,lis)

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
//typedef pair<ll,ll>P;
#define N 100010
#define M 200010
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const int MOD=1e9+,inv2=(MOD+)/;
double eps=1e-;
int INF=1e9;
int inf=0x7fffffff;
int dx[]={-,,,};
int dy[]={,,-,}; struct node
{
int x,y;
}q[N]; int dp[N],a[N],b[N],c[N],d[N],pre[N],ans[N],n; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} int lis()
{
q[].x=;
q[].y=;
rep(i,,n)
{
q[i].x=INF;
q[i].y=;
}
rep(i,,n) pre[i]=;
int s=;
rep(i,,n)
if(c[i])
{
s++;
int l=,r=s,last=;
while(l<=r)
{
int mid=(l+r)>>;
if(q[mid].x<=a[i]){last=mid; l=mid+;}
else r=mid-;
}
dp[i]=last; pre[i]=q[last].y;
if(q[last+].x>a[i]||q[last+].y==)
{
q[last+].x=a[i];
q[last+].y=i;
}
}
int res=,k=;
rep(i,,n)
if(c[i]&&dp[i]>res){res=dp[i]; k=i;}
rep(i,,n) d[i]=;
while(k)
{
d[k]=;
k=pre[k];
}
return res;
} void solve()
{
n=read();
rep(i,,n) a[i]=read();
rep(i,,n) b[i]=read();
rep(i,,n) c[i]=;
ans[n]=lis();
per(i,n-,)
{
c[b[i+]]=;
if(d[b[i+]]) ans[i]=lis();
else ans[i]=ans[i+];
}
rep(i,,n-) printf("%d ",ans[i]);
printf("%d\n",ans[n]);
} int main()
{
int cas=read();
while(cas--) solve();
return ;
}