逐月新星杯
B. 拓扑图计数
题目描述
给定一个排列
思路
我们对于每个点
空间复杂度
思路
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 200001, MOD = 998244353;
int n, tr[MAXN], ans = 1;
void update(int p, int x) {
for(; p <= n; tr[p] = max(tr[p], x), p += (p & -p)) {
}
}
int Getmax(int p) {
int Max = 0;
for(; p; Max = max(Max, tr[p]), p -= (p & -p)) {
}
return Max;
}
int Pow(int a, int b) {
int ret = 1;
for(; b; a = 1ll * a * a % MOD, b >>= 1) {
if(b & 1) {
ret = 1ll * ret * a % MOD;
}
}
return ret;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n;
for(int i = 1, x; i <= n; ++i) {
cin >> x;
int last = Getmax(n - x + 1);
update(n - x + 1, i);
ans = 1ll * ans * (!last ? Pow(2, i - 1) : 1ll * Pow(2, last - 1) * (Pow(2, i - last) - 1 + MOD) % MOD) % MOD;
}
cout << ans;
return 0;
}
D. 括号子区间
题目描述
我们定义一个合法括号串为:
- 空串是合法括号串。
- 若
是合法括号串,则 也是合法括号串。 - 若
是合法括号串,则 也是合法括号串。
现在你要构造一个括号串
是一个合法括号串。
求满足条件最大数量。
思路
我们考虑两个条件
,那么可以兼容。 ,由于题目保证了 为偶数,所以也可以兼容。- 否则说明
相交,如果相交的长度为偶数那么可以兼容,否则不行。
由于相交且相交部分为奇数的情况一定满足其
最后跑一遍二分图最大匹配求出最大独立集即可。
空间复杂度
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 501;
int n, m, l[MAXN], r[MAXN], ans, pl[MAXN], pr[MAXN], dist[MAXN];
bool flag[MAXN], vis[MAXN];
vector<int> e[MAXN];
bool bfs() {
fill(vis + 1, vis + m + 1, 0);
fill(dist + 1, dist + m + 1, 0);
queue<int> que;
for(int i = 1; i <= m; ++i) {
if(l[i] % 2 && !pl[i]) {
que.push(i);
dist[i] = 1;
}
}
for(; !que.empty(); ) {
int u = que.front();
que.pop();
for(int v : e[u]) {
if(!pr[v]) {
return 1;
}
if(!dist[pr[v]]) {
dist[pr[v]] = dist[u] + 1;
que.push(pr[v]);
}
}
}
return 0;
}
bool dfs(int u) {
if(vis[u]) {
return 0;
}
vis[u] = 1;
for(int v : e[u]) {
if(!pr[v] || (dist[pr[v]] == dist[u] + 1 && dfs(pr[v]))) {
pl[u] = v, pr[v] = u;
return 1;
}
}
return 0;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= m; ++i) {
cin >> l[i] >> r[i];
}
for(int i = 1; i <= m; ++i) {
for(int j = i + 1; j <= m; ++j) {
if((r[i] >= l[j] && r[i] < r[j] && l[i] < l[j] && (r[i] - l[j] + 1) % 2) || (r[j] >= l[i] && r[j] < r[i] && l[j] < l[i] && (r[j] - l[i] + 1) % 2)) {
if(l[i] % 2) {
e[i].emplace_back(j);
flag[j] = 1;
}else {
e[j].emplace_back(i);
}
}
}
}
for(; bfs(); ) {
for(int i = 1; i <= m; ++i) {
ans += (l[i] % 2 && !pl[i] && dfs(i));
}
}
cout << m - ans;
return 0;
}
本文作者:yaosicheng124
本文链接:https://www.cnblogs.com/yaosicheng124/p/18498243
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步