AT_arc182_a [ARC182A] Chmax Rush!题解

ARC182A Chmax Rush!

一个比较糖的做法。

考虑如果第 i i i 次操作选择向左进行操作,则对于 j < i j<i j<i 且 V j > V i V_j>V_i Vj>Vi 的操作 j j j,一定有 P j > P i P_j>P_i Pj>Pi(否则无论第 j j j 次操作向左还是向右第 i i i 次操作都无法向左走),且对于这些操作 j j j,我们要求他们必须向右进行操作。

于是有一个很糖的 DP,设 d p i , j , 0 / 1 dp_{i,j,0/1} dpi,j,0/1 表示考虑前 i i i 个操作,所有 V ≥ j V \ge j V≥j 的操作全部向左/全部向右的方案数。

时间复杂度 O ( N Q ) O(NQ) O(NQ)。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
int n,q,cnt=0;
struct js
{
	int p,v,id,vv;
}a[5005];
bool cmp(js x,js y)
{
	return x.vv<y.vv;
}
bool cmpp(js x,js y)
{
	return x.id<y.id;
}
int dp[5005][5005][2],dpp[5005];
int tree[5005],tr[5005];
int lowbit(int x){return x&(-x);}
void update(int x,int y)
{
	for(int i=x;i<=cnt;i+=lowbit(i)) tree[i]=max(tree[i],y),tr[i]=min(tr[i],y);
}
int query(int x)
{
	int res=0;
	for(int i=x;i;i-=lowbit(i)) res=max(res,tree[i]);
	return res;
}
int qu(int x)
{
	int res=1e9+5;
	for(int i=x;i;i-=lowbit(i)) res=min(res,tr[i]);
	return res;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>q;
	for(int i=1;i<=q;i++) 
	{
		cin>>a[i].p>>a[i].vv;
		a[i].id=i;
	}
	sort(a+1,a+1+q,cmp);
	for(int i=1;i<=q;i++)
		if(i==1||a[i].vv!=a[i-1].vv) cnt++,a[i].v=cnt;
		else a[i].v=cnt;
	sort(a+1,a+1+q,cmpp);
	memset(tr,127,sizeof(tr));
	dpp[0]=1;
	for(int i=0;i<=cnt;i++) dp[0][i][0]=dp[0][i][1]=1;
	for(int i=1;i<=q;i++)
	{
		a[i].v=cnt-a[i].v+1;
		if(query(a[i].v-1)<a[i].p) dpp[i]=(dpp[i]+dp[i-1][a[i].v-1][0])%mod;	
		if(qu(a[i].v-1)>a[i].p) dpp[i]=(dpp[i]+dp[i-1][a[i].v-1][1])%mod;
		for(int j=0;j<=cnt;j++)
			if(j<a[i].v)
			{
				if(query(a[i].v-1)==0||query(j)==0) 	dp[i][j][0]=dpp[i];
				else if(query(a[i].v-1)<a[i].p) dp[i][j][0]=(dp[i][j][0]+dp[i-1][a[i].v-1][0])%mod;
				if(query(a[i].v-1)==0||query(j)==0) 	dp[i][j][1]=dpp[i];
				else if(qu(a[i].v-1)>a[i].p) dp[i][j][1]=(dp[i][j][1]+dp[i-1][a[i].v-1][1])%mod;
			}
			else
			{
				if(query(a[i].v-1)==0) 
				{
					dp[i][j][0]=dp[i-1][j][0];
					dp[i][j][1]=dp[i-1][j][1];
				}
			}
		update(a[i].v,a[i].p);
	}
	cout<<dpp[q];
	return 0;
} 
相关推荐
一碗甜汤ᐝ几秒前
高级算法分析与设计 | 常见 NP-Complete 问题总结
算法·np-complete·算法分析与设计·np完备问题
fj800j4 分钟前
首助记账本新增「标签管理」功能:跨分类归集项目账目,一个账本管完所有事
数据结构·经验分享·笔记·学习·分布式账本
垆边人似月.14 分钟前
分割数组的最大值最小化(200分 / 二分答案 + 贪心)
数据结构·算法·排序算法
CQU_JIAKE16 分钟前
10.7【A】
算法
Dfreedom.38 分钟前
分类算法的统一视角:从方差最大化到概率建模再到损失函数
算法·支持向量机·分类
汉克老师38 分钟前
GESP2026年9月认证C++八级( 第三部分编程题(2、末班车))精讲
c++·gesp·小学生·学c++编程
Nebula_g1 小时前
JavaSE加强:Commons-io框架
java·开发语言·算法·javase
梦帮科技1 小时前
【3.0修订版】音乐权利 NFT:MusicRightsNFT 的确权思想与授权关联
网络协议·算法·web3·区块链·密码学·智能合约·零知识证明
傲世仙尊2 小时前
C++起步-命名空间解决命名冲突与cin-cout缺省参数
开发语言·c++
Dfreedom.2 小时前
基于PCA的光谱物质识别分析
算法