P3364 Cool loves touli 题解
前置知识
解法
先将英雄按 \(\{ l \}\) 升序排序,从而减少一维偏序。
设 \(f_{i}\) 表示以 \(i\) 结尾的最长合法序列长度,状态转移方程为 \(f_{i}=\max\limits_{j=1}^{i-1}\{ [a_{j} \le s_{i} \land w_{j} \le a_{i}] \times f_{j}+1 \}\) 。
然后就是 CDQ 分治优化 DP 的板子题了。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define sort stable_sort
#define endl '\n'
struct node
{
int l,s,w,a,id;
}q[100010];
struct BIT
{
int c[100000010];
int lowbit(int x)
{
return (x&(-x));
}
void add(int n,int x,int val)
{
for(int i=x;i<=n;i+=lowbit(i))
{
c[i]=max(c[i],val);
}
}
int getsum(int x)
{
int ans=0;
for(int i=x;i>=1;i-=lowbit(i))
{
ans=max(ans,c[i]);
}
return ans;
}
void del(int n,int x)
{
for(int i=x;i<=n;i+=lowbit(i))
{
c[i]=0;
}
}
}T;
int f[100010];
bool cmpl(node a,node b)
{
return a.l<b.l;
}
bool cmps(node a,node b)
{
return a.s<b.s;
}
bool cmpa(node a,node b)
{
return a.a<b.a;
}
bool cmpid(node a,node b)
{
return a.id<b.id;
}
void cdq(int l,int r,int k)
{
if(l==r)
{
return;
}
int mid=(l+r)/2,x,y;
cdq(l,mid,k);
sort(q+l,q+mid+1,cmpa);
sort(q+mid+1,q+r+1,cmps);
for(x=l,y=mid+1;y<=r;y++)
{
for(;q[x].a<=q[y].s&&x<=mid;x++)
{
T.add(k,q[x].w,f[q[x].id]);
}
f[q[y].id]=max(f[q[y].id],T.getsum(q[y].a)+1);
}
x--;
for(int i=l;i<=x;i++)
{
T.del(k,q[i].w);
}
sort(q+mid+1,q+r+1,cmpid);
cdq(mid+1,r,k);
}
int main()
{
int n,ans=0,i;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>q[i].l>>q[i].s>>q[i].w>>q[i].a;
f[i]=1;
}
sort(q+1,q+1+n,cmpl);
for(i=1;i<=n;i++)
{
q[i].id=i;
}
cdq(1,n,100000000);
for(i=1;i<=n;i++)
{
ans=max(ans,f[i]);
}
cout<<ans<<endl;
return 0;
}
后记
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18441054,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。