P10600 BZOJ4350 括号序列再战猪猪侠 Solution

你是图论大神,首先拓扑排序一遍给定的限制,如果有环直接输出 \(0\)

你是 bitset 大神,考虑拓扑排序出一个布尔数组 \(F_{i,j}\),表示 \(match_j\) 在限制中是否小于 \(match_i\)。然后再或一下得到一个数组 \(s_{l,r,k}\) 表示 \(l\)\(r\) 中是否存在任意一个满足其 \(match\) 值大于 \(match_k\),也就是 \(F\)\(l\) 按位或到 \(r\)

你是 dp 大神,定义状态 \(f_{l,r}\) 表示第 \(l\) 个到第 \(r\) 个左括号及其右括号填满的方案数。你发现有两种转移:

  • 形如 (S),也就是左端点包住整个区间,仅当 \(match_l\) 可以大于 \(match_{l+1},match_{l+2},\cdots,match_{r}\),也就是 \(s_{l+1,r,l}=0\) 时可以转移,\(f_{l,r}\leftarrow f_{l+1,r}\)
  • 形如 ST,也就是拆分成两个并列的区间,我们设 \(k\) 为拆分出来的左区间的右端点,当且仅当没有限制使得右区间的 \(match\) 会小于左边,也就是 \(s_{l,k}\)\([k+1,r]\) 这一段都为 \(0\),可以通过对 \(s\) 前缀和简单判断。\(f_{l,r}\leftarrow f_{l,k}\times f_{k+1,r}\)

然后你轻松码完代码,发现样例都过不了。第三组数据你输出 \(2\),而非 \(1\)。你发现对于 ()()(),你在处理 \(f_{1,3}\) 时,在 \(k=1,2\) 的时候都会做贡献,但是是重复的贡献,然后倒闭。所以你决定修改方程。

为了避免重复贡献,我们考虑钦定左端点包住左区间,也就是:

  • 形如 (S)T,在上文第二种转移的基础上,我们保证 \(l\) 能包住 \([l+1,k]\),也就是 \(match_l\) 可以大于 \(match_{l+1}\)\(match_k\) 的所有,转移:\(f_{l,r}\leftarrow f_{l+1,k}\times f_{k+1,r}\)
  • 这时候,你睿智地发现,上文第一种转移其实就等于 \(k=r\) 的时候转移,于是可以合并两部分的代码。

然后你就通过了。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 310;
const LL MOD = 998244353;
int n, m, in[N]; LL DP[N][N];
vector<int> G[N]; bitset<N> f[N], ff[N][N]; int pre[N][N][N];LL DFS(int l, int r) {if (l >= r) return 1; // 因为 k 可能为 r,导致区间 r+1,r 产生贡献,所以钦定 l>r 也为 1if (DP[l][r] != -1) return DP[l][r];LL ret = 0, pt = l;while (pt < r && !f[pt + 1][l]) ++ pt; // 找到 l 最远能包住的点for (int k = l; k <= pt; k ++) if (pre[l][k][r] == pre[l][k][k]) {ret = (ret + DFS(l + 1, k) * DFS(k + 1, r)) % MOD;  // 转移} return DP[l][r] = ret;
}int main() {freopen(".in", "r", stdin); freopen(".out", "w", stdout);ios :: sync_with_stdio(0); cin.tie(0); cout.tie(0);int _; cin >> _;while (_ --) {cin >> n >> m; for (int i = 1; i <= n; i ++) in[i] = 0, G[i].clear(), f[i].reset();for (int i = 1, u, v; i <= m; i ++) {cin >> u >> v; in[v] ++; G[u].emplace_back(v);} queue<int> q; int cnt = 0;for (int i = 1; i <= n; i ++) if (!in[i]) q.push(i);while (!q.empty()) {++ cnt; int u = q.front(); q.pop();for (int v : G[u]) {f[v].set(u); f[v] |= f[u]; in[v] --; if (!in[v]) q.push(v);}} if (cnt < n) { cout << "0\n"; continue; }for (int i = 1; i <= n; i ++) {ff[i][i] = f[i];for (int j = i + 1; j <= n; j ++) ff[i][j] = ff[i][j - 1] | f[j];} // 也就是上文的 s 数组。for (int i = 1; i <= n; i ++) for (int j = i; j <= n; j ++) {for (int k = 1; k <= n; k ++) pre[i][j][k] = pre[i][j][k - 1] + ff[i][j][k];} // 前缀和便于判断。for (int i = 1; i <= n; i ++) for (int j = 1; j <= n; j ++) DP[i][j] = -1;cout << DFS(1, n) << "\n";}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/881135.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt监控设备离线检测/实时监测设备上下线/显示不同的状态图标/海康大华宇视华为监控系统

一、前言说明 监控系统中一般有很多设备,有些用户希望知道每个设备是否已经上线,最好有不同的状态图标提示,海康的做法是对设备节点的图标和颜色变暗处理,离线的话就变暗,有可能是加了透明度,而大华的处理是有个清晰的图标表示,上线图标右下角有个绿色指示灯,离线的右下…

VIP视频解析之小工具(免费自取)

我们通常会因为看电影但是需要vip却没有足够生活费去支持的困扰 我就在想有没有白嫖的方法呢(bushi 就在我苦恼的时候我发现了一个方法————就是被称为:解析 的技术这玩意就是最好的选择 但是可能部分人在刚刚接触的时候不会用的于是我就写了一个小软件来支持(只支持wind…

2025年值得推荐的 8 款 WPF UI 控件库

前言 今天大姚给大家分享 8 款开源、美观、功能强大、简单易用的WPF UI控件库,希望可以帮助到有需要的同学。 WPF介绍 WPF 是一个强大的桌面应用程序框架,用于构建具有丰富用户界面的 Windows 应用。它提供了灵活的布局、数据绑定、样式和模板、动画效果等功能,让开发者可以…

github官网运行加速方法

github官网打不开的原因 访问github官网时是直接访问域名即github.com,中间有个域名通过DNS解析的过程,将域名解析为对应的ip地址,其实主要时间都是花在了DNS解析上,导致了github有时候能打开,有时候打不开,有时候访问很慢。 解决方案 1、Windows系统打开cmd,输入下列命…

关于AI生成艺术、自动驾驶汽车和Nutella片

Foto di Barbara Zandoval su Unsplash前言:当前时代人们似乎仍然坚信AI没有人类这样的创造力的!那人类的创造力又是什么呢?不也是从开始拥有认识能力,然后逐渐进化到现在空前的创造力的吗?如果AI也自我进化,创造力又能意味着什么? 我是个万事通。作为一名自由职业的在线…

MathType 7.4下载与安装

《数学公式编辑器(MathType)》 [1]是一款专业的数学公式编辑工具,理科生专用的工具。mathtype公式编辑器能够帮助用户在各种文档中插入复杂的数学公式和符号。 数学公式编辑器工具可以轻松输入各种复杂的公式和符号,与Office文档完美结合,显示效果超好,比Office自带的公式编…

支付流程设计常见问题及最佳实践

在实际操作中,支付流程常常面临诸多问题。本文将深入探讨支付流程设计中的常见问题及其最佳实践,供大家参考。今天聊一下支付流程设计的一些常见总是及最佳实践,包括: 组合支付要不要拆支付流水,前端轮询查哪个域,查询要不要穿透到外部渠道,为什么要做同步受理异步处理,…

原 侧边栏公告

<!-- 配置项详情见 https://bndong.github.io/Cnblogs-Theme-SimpleMemory/v2/#/Docs/Customization/config --><script type="text/javascript"> window.cnblogsConfig = {info: {name: , //「待填内容」 用户名startDate: , //「待填内容」 入园时间,…

读算法简史:从美索不达米亚到人工智能时代11搜索网络

20世纪70年代小型计算机普及,苹果推出Apple和Macintosh;蒂姆伯纳斯-李提出万维网,改变了网络访问方式;亚马逊采用个性化推荐算法;谷歌开发PageRank算法,引领网络搜索和关键字广告。1. 小型计算机 1.1. 到了20世纪70年代,小型计算机已在科研院所、大学和大公司中广泛应用…

Roslyn 源代码生成器 SourceGenerator 获取代码文件的本地绝对路径

本文告诉大家如何在源代码生成器 SourceGenerator 里面获取代码文件的本地文件的绝对路径从 compilation 的 Options 拿到 SourceReferenceResolver 对象,调用其 NormalizePath 方法,传入 SyntaxTree 的 FilePath 参数即可 正常项目的 SourceReferenceResolver 都是存在的,尽…

纯 CSS 来计算当前窗口的宽高

在平时我想要计算浏览器窗口的宽度高度的时候,我们会使用 resize 事件去获取,也就是 JavaScript 的方式去获取窗口的宽度高度。 今天给大家分享一个使用纯 CSS 就能计算窗口宽度高度的方法定义自定义属性: 使用@property规则来定义--vw和--vh作为自定义的CSS属性。这些属性…

宏定义

宏定义 # 和 ## #号(将符号转为字符串) 这条定义中,定义了一个 PRINT 的宏函数预处理器遇到这样的宏,会将 #a 替换成以字符串表示的参数 a 例如:##号(连接符:将2个表达式连接到一起)预处理器会将这2条宏扩展成下面的代码我们可以看到:这2条宏定义其实就是定义了2个成员…