当前位置:网站首页>2022杭电多校第三场 L题 Two Permutations
2022杭电多校第三场 L题 Two Permutations
2022-08-05 00:18:00 【Rain Sure】
题目链接
题目大意
给定两个长度为 n n n的排列 a , b a,b a,b和一个由两个排列组成的长度为 2 ∗ n 2*n 2∗n的数组 c c c,每次从两个排列中任意一个的最左端取出一个数放到 c [ i ] c[i] c[i]里,请问构造出 c c c数组的方案数。
题解
比赛的时候想了线性DP的做法,感觉很牛逼。后来看题解,发现大家的做法更优秀。。。尤其是jiangly的模拟大法,让我大受震撼!!!
设 f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k] 表示第 i i i个数从 j j j数组中选, i − 1 i - 1 i−1个数从 k k k数组中选,还需要一个额外的数组 g g g记录选择哪个数组。具体转移看代码~ ( 0 < = j < = 1 ) ( 0 < = k < = 1 ) (0 <= j <= 1) (0 <= k <= 1) (0<=j<=1)(0<=k<=1)
代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0);
#define x first
#define y second
#define endl '\n'
const int inf = 1e9 + 10;
const int maxn = 300010, M = 2000010;
const int mod = 998244353;
typedef pair<int,int> PII;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
int h[maxn], e[M], w[M], ne[M], idx;
int dx[4] = {
-1, 0, 1, 0}, dy[4] = {
0, -1, 0, 1};
int cnt;
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
int n;
int a[maxn], b[maxn], c[maxn * 2];
int f[maxn * 2][2][2];
int g[maxn * 2][2][2];
int main()
{
int t; scanf("%d", &t);
while(t --)
{
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]);
for(int i = 1; i <= n * 2; i ++) scanf("%d", &c[i]);
memset(f, 0, sizeof f); memset(g, 0, sizeof g);
if(c[1] == a[1] && c[2] == a[2]) {
f[2][0][0] = 1;
g[2][0][0] = 2;
}
if(c[1] == a[1] && c[2] == b[1]){
f[2][1][0] = 1;
g[2][1][0] = 1;
}
if(c[1] == b[1] && c[2] == a[1]){
f[2][0][1] = 1;
g[2][0][1] = 1;
}
if(c[1] == b[1] && c[2] == b[2]){
f[2][1][1] = 1;
g[2][1][1] = 0;
}
for(int i = 3; i <= n * 2; i ++){
// f[i][0][0]
int id0 = g[i - 1][0][0], id1 = g[i - 1][0][1];
// cout << id0 << ' ' << id1 << endl;
if(a[id0 + 1] == c[i]) f[i][0][0] = (f[i][0][0] + f[i - 1][0][0]) % mod, g[i][0][0] = id0 + 1;
if(a[id1 + 1] == c[i]) f[i][0][0] = (f[i][0][0] + f[i - 1][0][1]) % mod, g[i][0][0] = id1 + 1;
// f[i][0][1]
id0 = g[i - 1][1][0], id1 = g[i - 1][1][1];
if(a[id0 + 1] == c[i]) f[i][0][1] = (f[i][0][1] + f[i - 1][1][0]) % mod, g[i][0][1] = id0 + 1;
if(a[id1 + 1] == c[i]) f[i][0][1] = (f[i][0][1] + f[i - 1][1][1]) % mod, g[i][0][1] = id1 + 1;
// f[i][1][0]
id0 = g[i - 1][0][0], id1 = g[i - 1][0][1];
if(b[(i - id0)] == c[i]) f[i][1][0] = (f[i][1][0] + f[i - 1][0][0]) % mod, g[i][1][0] = id0;
if(b[i - id1] == c[i]) f[i][1][0] = (f[i][1][0] + f[i - 1][0][1]) % mod, g[i][1][0] = id1;
// f[i][1][1]
id0 = g[i - 1][1][0], id1 = g[i - 1][1][1];
if(b[i - id0] == c[i]) f[i][1][1] = (f[i][1][1] + f[i - 1][1][0]) % mod, g[i][1][1] = id0;
if(b[i - id1] == c[i]) f[i][1][1] = (f[i][1][1] + f[i - 1][1][1]) % mod, g[i][1][1] = id1;
}
int res = 0;
for(int i = 0; i < 2; i ++){
for(int j = 0; j < 2; j ++){
res = (res + f[n * 2][i][j]) % mod;
}
}
printf("%d\n", res);
}
return 0;
}
边栏推荐
猜你喜欢

找不到DiscoveryClient类型的Bean

Three tips for you to successfully get started with 3D modeling
手写分布式配置中心(1)

oracle创建表空间

TinyMCE disable escape

MongoDB权限验证开启与mongoose数据库配置

Privacy Computing Overview

redis可视化管理软件Redis Desktop Manager2022

3. Actual combat---crawl the result page corresponding to Baidu's specified entry (a simple page collector)

MAUI Blazor 权限经验分享 (定位,使用相机)
随机推荐
The applicable scenarios and common product types of the KT148A electronic voice chip ic solution
Essential knowledge for entry-level 3D game modelers
数据类型-整型(C语言)
网站最终产品页使用单一入口还是多入口?
2 用D435i运行VINS-fusion
克服项目管理中恐惧心理
10 种常见的BUG分类
Brainstorm: Complete Backpack
性能测试如何准备测试数据
2022杭电多校第一场 1004 Ball
关于我仔细检查审核过关于工作人员页面,返回一个所属行业问题
tiup telemetry
软件测试面试题:黑盒测试、白盒测试以及单元测试、集成测试、系统测试、验收测试的区别与联系?
leetcode:267. 回文排列 II
【Valentine's Day special effects】--Canvas realizes full screen love
Mysql_12 多表查询
LeetCode Hot 100
英特尔WiFi 7产品将于2024年亮相 最高速度可达5.8Gbps
导入JankStats检测卡帧库遇到问题记录
Will domestic websites use Hong Kong servers be blocked?