首页 > 其他分享 >[题解]Pa?sWorD(2023ICPC网络预选赛第一场I题)

[题解]Pa?sWorD(2023ICPC网络预选赛第一场I题)

时间:2023-09-18 11:57:52浏览次数:63  
标签:return int 题解 36 2023ICPC Pa && dp

I Pa?sWorD

下次不要认为2e8可以莽过去了


思路

计数DP + 状压(其实也可以不压) + 前缀和优化(倒着写是差分)

dp[i][j][k]表示第i位填j,状态为k的方案数

k这一维用于状态压缩,表示 数字、大写、小写 是否出现

前缀和优化:在处理?的时候,暴力会有62X62X8的单次复杂度,但不难发现,关于上次一选择填什么的那层循环可以做个和
具体一些:先不考虑xx这种情况,?直接整体转移,再减去xx这种情况的贡献,直接优化下来一个62

完整代码

#include<bits/stdc++.h>
using namespace std ;
inline int read(){
	int s=0,w=1 ; char g=getchar() ; while( g>'9' || g<'0' ){ if( g=='-')w=-1; g=getchar() ; }
	while( g>='0' && g<='9' )s=s*10+g-'0',g=getchar() ; return s*w ; 
}
#define ll long long
const int MAXN = 100005 ; 
const ll mod = 998244353 ; 
string s ; 
ll a[MAXN] , dp[4][64][10] ;
inline ll add( ll x , ll y ){
	return (x+y+mod)%mod ; 
}
inline int trans( char g ){
	if( g >='0' && g <='9' )return (int)(g-'0') ; 
	if( g >='a' && g <='z' )return (int)(g-'a'+10) ; 
	if( g >='A' && g <='Z' )return (int)(g-'A'+36) ;
	else return -1 ; 
}
inline int kind( int x ){
	if( x == -1 )return -1 ; 
	if( x >= 0 && x <= 9 )return 4  ;
	if( x >= 10 && x < 36 )return 2 ; 
	return 1 ; 
}
void prework(){
	if( a[1] == -1 ){
		for( int i = 0 ; i <= 61 ; ++i )dp[1][i][kind(i)] = 1 ; 
		return ; 
	}
	if( a[1] >= 0 && a[1] <= 9 ){
		dp[1][a[1]][4] = 1 ; return ; 
	}
	if( a[1] >= 10 && a[1] < 36 ){
		dp[1][a[1]][2] = dp[1][a[1]+26][1] =1 ; return ; 
	}
	if( a[1] >= 36 ){
		dp[1][a[1]][1] = 1 ; return ; 
	}
}
int main(){
	ios::sync_with_stdio(false) ; 
	int n ; cin>>n ;  cin>>s ; 
	for( int i = 0 ; i < n ; ++i )
		a[i+1] = trans(s[i]) ; 
	prework() ; 
	for( int i = 2 ; i <= n ; ++i ){
		for( int j = 0 ; j <= 61 ; ++j )
			for( int k = 0 ; k <= 7 ; ++k )dp[i&1][j][k] = 0 ;
		int ka = kind( a[i] ) ; 
		if( ka == -1 ){ // ?
			ll tmp[8] = { 0,0,0,0,0,0,0,0} ; 
			for( int k = 0 ; k <= 7 ; ++k )
				for( int y = 0 ; y <= 61 ; ++y )
					tmp[k] += dp[(i-1)&1][y][k] , tmp[k] %= mod;
			for( int x = 0 ; x <= 61 ; ++x ){
				for( int k = 0 ; k <= 7 ; ++k )
					if( k&kind(x)  ){
						dp[i&1][x][k] = add( tmp[k-kind(x)] , tmp[k] );
						dp[i&1][x][k] = add( dp[i&1][x][k] , -dp[(i-1)&1][x][k] );
						dp[i&1][x][k] = add( dp[i&1][x][k] , -dp[(i-1)&1][x][k-kind(x)] );
					}
			}
		}
		else if( ka == 4 ){// number
			for( int x = a[i] ; x <= a[i] ; ++x ){
				for( int k = 0 ; k <= 7 ; ++k )
					if( k&kind(x) )
					for( int y = 0 ; y <= 61 ; ++y ){
						if( y == x )continue ; 
						dp[i&1][x][k] = add( dp[i&1][x][k] , dp[(i-1)&1][y][k] );
						dp[i&1][x][k] = add( dp[i&1][x][k] , dp[(i-1)&1][y][k-kind(x)] );
					}
			}
		} 
		else if( ka == 1 ){ // upper
			for( int x = a[i] ; x <= a[i] ; ++x ){
				for( int k = 0 ; k <= 7 ; ++k )
					if( k&kind(x) )
					for( int y = 0 ; y <= 61 ; ++y ){
						if( y == x )continue ; 
						dp[i&1][x][k] = add( dp[i&1][x][k] , dp[(i-1)&1][y][k] );
						dp[i&1][x][k] = add( dp[i&1][x][k] , dp[(i-1)&1][y][k-kind(x)] );
					}
			}
		}
		else if( ka == 2 ){ // lower
			for( int x = a[i] ; x <= 61 ; x += 26 ){
				for( int k = 0 ; k <= 7 ; ++k )
					if( k&kind(x) )
					for( int y = 0 ; y <= 61 ; ++y ){
						if( y == x )continue ; 
						dp[i&1][x][k] = add( dp[i&1][x][k] , dp[(i-1)&1][y][k] );
						dp[i&1][x][k] = add( dp[i&1][x][k] , dp[(i-1)&1][y][k-kind(x)] );
					}
			}
		}
	}
	ll ans = 0 ;
	for( int i = 0 ; i <= 61 ; ++i )ans = add( ans , dp[n&1][i][7] ) ; 
	cout<<ans%mod  ;
}

标签:return,int,题解,36,2023ICPC,Pa,&&,dp
From: https://www.cnblogs.com/ssw02/p/17711499.html

相关文章

  • 20个最佳实践提升Terraform工作流程|Part 1
    Terraform是管理基础设施及代码(IaC)最常用的工具之一,它能使我们安全且可预测地对基础设施应用更改。刚开始上手Terraform可能会感觉有些不容易,但很快就能对该工具有基本的了解,随之可以开始运行命令、创建和重构Terraform代码。在此过程中,许多新用户面临着如何正确构建代码、使......
  • 在MySQL的PREPARE中绑定WHERE IN子句参数
    1.PREPARE简介在MySQL中,PREPARE是一种用于准备执行动态SQL语句的机制。通过PREPARE,你可以将一个SQL查询或操作的查询计划(执行计划)准备好,然后在稍后的时间点执行它,而不是立即执行。这带来了以下好处:SQL注入防护:使用PREPARE可以在准备SQL语句时进行参数绑定,从而防......
  • Death DBMS题解(AC自动机)
    题目传送门CF1437G好题观察这道题,发现有关字串的题目,一般来说,这种题都要构建\(AC\)自动机,所以考虑构建。构建之后,原来的所有\(fail\)是一个树形结构。解法\(1\):考虑从询问入手,那么对于每一个询问,等价于就是查询每一个\(Q_i\)包含的后缀的最大值,再对这些最大值取\(max......
  • 粒子群算法(Particle Swarm Optimization, PSO)
    ParticleSwarmOptimization算法原理参考:https://zhuanlan.zhihu.com/p/404198434Question使用PSO算法计算函数$f(x)=x_1^2+3x_2^2-x_1+2x_2-5$在\(x\in[-100,100]^2\)上的最小值CodeimportnumpyasnpfromtypingimportListParametersdim=......
  • 题解 LOJ2549【[JSOI2018] 战争】
    problem给你两个平面凸多边形\(A,B\),\(Q\)次询问,每次询问是一个向量\(\vecv\),回答\(A\)与\(B+\vecv\)是否有交。\(n,Q\leq10^5\)。solution观察闵可夫斯基和(Minkowskysum)的定义,若将这个运算定义为\((*)::[Point]\to[Point]\to[Point]\),则满足:\[A*B=\{......
  • 关于 Spartacus My Account 菜单的数据源 - NavigationNode
    有朋友询问Spartacus的MyAccount菜单里,Mycompany菜单项的数据源是什么?Spartacus启动时,我们观察到这个OCCAPI:/occ/v2/powertools-spa/cms/pages?lang=en&curr=USD在其响应数据里,观察到navigationnode里包含了一个叫做MyCompany的菜单项:Backoffice是SAPCom......
  • Kubernetes NameSpace
    Namespace名称空间,为资源对象的名称提供了限定条件或作用范围,它为使用同一集群的多个团队或项目提供了逻辑上的隔离机制,降低或消除了资源对象名称冲突的可能性。namespace命令空间,后面简称ns。在K8s上面,大部分资源都受ns的限制,来做资源的隔离,少部分如pv,clusterRole等不受ns控制#查......
  • 【C#】.NET6.0后支持的顶级语句使用命名空间(namespace)问题
    创建C#项目且使用.Net6.0以上的版本时,默认code会使用顶级语句形式:1、略去staticvoidMain(String[]args)主方法入口;2、隐式使用(即隐藏且根据代码所需要的类自动调用)其他命名空间(包括):usingSystem;usingSystem.IO;usingSystem.Collections.Generic;usingSystem.Linq;......
  • LVS+Keepalived群集
    1.Keepalived是什么?Keepalived是Linux下一个轻量级别的高可用解决方案。可以实现服务的高可用或热备,用来防止单点故障的问题,Keepalived起初是为LVS设计的,专门用来监控集群系统中各个服务节点的状态,它根据TCP/IP参考模型的第三、第四层、第五层交换机制检测每个服务节点的状态,如果......
  • (数据科学学习手札154)geopandas 0.14版本新特性一览
    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes1简介大家好我是费老师,就在前两天,Python生态中的GIS运算神器geopandas发布了其0.14.0新版本,在这次新版本更新中,不仅是新增了许多矢量计算API,还开始为日后正式发布1.0版本做准备,对......