Atcoders [ARC133B] Dividing Subsequence 题解

AT_arc133_b [ARC133B] Dividing Subsequence

模拟赛原题,来写篇题解。

只考虑匹配的状态,根据调和级数的数学知识,匹配的状态数不多,为 O(nlogn),考虑动态规划。

我们对于每个 ai 预处理出可以匹配的位置 ci,j 表示第 i 位可以匹配的第 j 个位置,记 fi,j 表示第 i 位匹配第 j 个可以匹配的位置的最长子序列长度。显然有以下转移方程:

fi,j=maxl<i,cl,k<ci,j{fl,k}+1

线段树优化 dp,每次把 fi,j 插到 ci,j 上,查询时直接查询 <ci,j 的位置即可,时间复杂度 O(nlog2n)

模拟赛时被卡常了,不过 Atcoders 上稳过。

#include <bits/stdc++.h>
using namespace std;
struct node
{
	int mx;
}tr[900000];
int n,a[300000],b[300000],p[300000],ans=0,cnt=0,rt=1;
vector<int>c[300000],f[300000];
void pushup(int x)
{
	tr[x].mx=max(tr[(x<<1)].mx,tr[(x<<1)|1].mx);
}

void update(int x,int l,int r,int p,int k)
{
	if(l==r)
	   {
	   	tr[x].mx=max(tr[x].mx,k);
	   	return;
	   }
	int mid=(l+r)>>1;
	if(p<=mid)update((x<<1),l,mid,p,k);
	else update((x<<1)|1,mid+1,r,p,k);
	pushup(x);
}

int query(int x,int l,int r,int lx,int rx)
{
	if(lx==0||rx==0)return 0;
	if(l>=lx&&r<=rx)return tr[x].mx;
	int mid=(l+r)>>1,ans=0;
	if(lx<=mid)ans=max(ans,query((x<<1),l,mid,lx,rx));
	if(rx>=mid+1)ans=max(ans,query((x<<1)|1,mid+1,r,lx,rx));
	return ans;
} 

int main()
{
	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]),p[b[i]]=i;
	for(int i=1;i<=n;i++)
	    for(int j=a[i];j<=n;j+=a[i])
	        c[i].push_back(p[j]);
	for(int i=0;i<c[1].size();i++)f[1].push_back(1);
	for(int i=0;i<c[1].size();i++)update(rt,1,n,c[1][i],f[1][i]);
	for(int i=2;i<=n;i++)
	    {
	    for(int j=0;j<c[i].size();j++)f[i].push_back(query(rt,1,n,1,c[i][j]-1)+1);
		for(int j=0;j<c[i].size();j++)update(rt,1,n,c[i][j],f[i][j]);
	    }
	for(int i=1;i<=n;i++)
	    for(int j=0;j<f[i].size();j++)
	        ans=max(ans,f[i][j]);
	printf("%d\n",ans);
	return 0;
}
posted @   w9095  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示