NOIP模拟赛 十八

news/2025/9/27 22:02:46/文章来源:https://www.cnblogs.com/qkhm/p/19115776

A.

神秘 DP 的神秘做法。

先考虑朴素 DP ,发现最短路是可以钦定的,具体的,设 \(1\) 到其最短路为 \(d\) ,则称其为第 \(d\) 层。

要求,每一层如果存在点,一定要向上一层连边,同层可以随便连边,非相邻层不可连边。

其中异或和只不过是状态里多设一维 0/1 的问题,以下略去。

\(f[d, i, k, j]\) 表示考虑完前 \(d\) 层,第 \(d\) 层有 \(k\) 个点,总共有 \(i\) 个点, \(j\) 条边的方案数。

转移枚举下一层选的点数 \(\Delta p\) 和连的边数 \(\Delta e\) ,提前预处理辅助数组,复杂度 \(O(n^8)\)

优化,没有必要同时枚举点数和边数的增量,可以将点依次填入,再决策边的连接。

对于 \(f[d, i, k, j]\) ,记 \(g[k, j]\) 表示下一层选了 \(k\) 个点,总共 \(j\) 条边的方案数。

(不定此层选了几条边是因为这样就可以不用卷积)

转移枚举选择了 \(t\) 条边,容斥得到式子 \(({k+k'\choose t} - {k'\choose t})\times g[k', j]\rightarrow g[k'+1,j+t]\)

再贡献给 \(f\) ,乘上重编号的系数。
复杂度 \(O(n^7)\)
(据说写的好看可以直接过)

点击查看

#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = a; i <= b; ++i)
#define rep(i, a, b) for (int i = a; i >= b; --i)
#define il inline
#define cmx(a, b) ((a) > (b) ? (a) : (b))
#define cmn(a, b) ((a) < (b) ? (a) : (b))
#define gmx(a, b) a = cmx(a, b)
#define gmn(a, b) a = cmn(a, b)template <typename T>
void _debug(const T& t) { std::cerr << t << '\n'; }
template <typename T, typename... Args>
void _debug(const T& t, const Args&...res) { std::cerr << t << ' '; _debug(res...); }
#define debug(...) _debug(#__VA_ARGS__ " =", __VA_ARGS__)const int LN = 50 + 1;
typedef long long ll;
typedef std::pair<int, int> PII;bool FIRPOS;int n, m, a[LN], mod, C[LN * LN][LN * LN], ans[LN * LN];
int f[2][2][LN][LN][LN * LN], g[2][LN][LN * LN];bool ENDPOS;il int add(int u, int v) { return u + v >= mod ? u + v - mod : u + v; }
il void upa(int& u, int v) { u = add(u, v); }
il int mul(ll u, ll v) { return u * v >= mod ? u * v % mod : u * v; }
il void upm(int& u, int v) { u = mul(u, v); }
il int MyPow(int a, int b) { int ans = 1; for (; b; b >>= 1, upm(a, a)) if (b & 1) upm(ans, a); return ans; }int main() {std::ios::sync_with_stdio(false),std::cin.tie(nullptr), std::cout.tie(nullptr);int c1 = clock();std::cin >> n >> mod; m = n * (n - 1) / 2;lep(i, 0, LN * LN - 1) { C[i][0] = 1;lep(j, 1, i) C[i][j] = add(C[i - 1][j], C[i - 1][j - 1]);}lep(i, 0, n - 1) std::cin >> a[i];if (n == 1) {std::cout << a[0] << '\n';return 0;}int p = 0; f[p][a[0]][1][1][0] = 1;lep(d, 1, n - 1) {std::memset(f[p ^ 1], 0, sizeof(f[p ^ 1]));lep(i, 1, n) lep(k, 1, i) {std::memset(g, 0, sizeof(g));lep(j, 0, m)g[0][0][j] = f[p][0][i][k][j], g[1][0][j] = f[p][1][i][k][j];lep(dl, 1, n - i) {lep(j, 0, m) {lep(t, 1, k + dl - 1) if (j + t <= m) {upa(g[a[d]][dl][j + t], mul(C[k + dl - 1][t], g[0][dl - 1][j])),upa(g[a[d] ^ 1][dl][j + t], mul(C[k + dl - 1][t], g[1][dl - 1][j]));if (dl > t)upa(g[a[d]][dl][j + t], mod - mul(C[dl - 1][t], g[0][dl - 1][j])),upa(g[a[d] ^ 1][dl][j + t], mod - mul(C[dl - 1][t], g[1][dl - 1][j]));}}}lep(dl, 1, n - i) lep(j, 0, m) upa(f[p ^ 1][0][i + dl][dl][j], mul(C[i + dl - 1][dl], g[0][dl][j])),upa(f[p ^ 1][1][i + dl][dl][j], mul(C[i + dl - 1][dl], g[1][dl][j]));}p ^= 1;lep(k, 1, n) lep(j, n - 1, m)upa(ans[j], f[p][1][n][k][j]);}lep(i, n - 1, m) std::cout << (ans[i] + mod) % mod << ' ';std::cout << '\n';#ifdef DEBUGstd::cerr << clock() - c1 << " ms " << fabs(&ENDPOS - &FIRPOS) / 1024 / 1024 << " MB\n";
#endifreturn 0;
}

考虑优化,我们将转移写成生成函数。

\(F_{i,k}=\sum_j f_{i,k,j}x^j\)\(G_k=\sum_j g_{k, j}x^j\)

则转移相当于 \(F_{i+k', k'} = F_{i, k}+{i+k'-1\choose k'}G_{k'}\)\(G_{k'+1}=G_{k'}((1+x)^k-1)(1+x)^{k'}\)

发现有很多 \(1+x\) ,我们维护 \(x\) 为占位符相当于把每个 \(1+x\) 又拆开了,很蠢。

直接定义 \(F_{i,k}=\sum_j f_{i,k,j}'(x+1)^j\)\(G_k=\sum_j g_{k, j}'(x+1)^j\)

那么转移就可以 \(O(1)\) 做了。

最后贡献的时候按照二项式定理拆开就好了。

复杂度 \(O(n^6)\)

点击查看

#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = a; i <= b; ++i)
#define rep(i, a, b) for (int i = a; i >= b; --i)
#define il inline
#define cmx(a, b) ((a) > (b) ? (a) : (b))
#define cmn(a, b) ((a) < (b) ? (a) : (b))
#define gmx(a, b) a = cmx(a, b)
#define gmn(a, b) a = cmn(a, b)template <typename T>
void _debug(const T& t) { std::cerr << t << '\n'; }
template <typename T, typename... Args>
void _debug(const T& t, const Args&...res) { std::cerr << t << ' '; _debug(res...); }
#define debug(...) _debug(#__VA_ARGS__ " =", __VA_ARGS__)const int LN = 50 + 1;
typedef long long ll;
typedef std::pair<int, int> PII;bool FIRPOS;int n, m, a[LN], mod, C[LN * LN][LN * LN], ans[LN * LN];
int f[2][2][LN][LN][LN * LN], g[2][LN][LN * LN];bool ENDPOS;il int add(int u, int v) { return u + v >= mod ? u + v - mod : u + v; }
il void upa(int& u, int v) { u = add(u, v); }
il int mul(ll u, ll v) { return u * v >= mod ? u * v % mod : u * v; }
il void upm(int& u, int v) { u = mul(u, v); }
il int MyPow(int a, int b) { int ans = 1; for (; b; b >>= 1, upm(a, a)) if (b & 1) upm(ans, a); return ans; }int main() {std::ios::sync_with_stdio(false),std::cin.tie(nullptr), std::cout.tie(nullptr);int c1 = clock();std::cin >> n >> mod; m = n * (n - 1) / 2;lep(i, 0, LN * LN - 1) { C[i][0] = 1;lep(j, 1, i) C[i][j] = add(C[i - 1][j], C[i - 1][j - 1]);}lep(i, 0, n - 1) std::cin >> a[i];if (n == 1) {std::cout << a[0] << '\n';return 0;}int p = 0; f[p][a[0]][1][1][0] = 1;lep(d, 1, n - 1) {std::memset(f[p ^ 1], 0, sizeof(f[p ^ 1]));lep(i, 1, n) lep(k, 1, i) {std::memset(g, 0, sizeof(g));lep(j, 0, m)g[0][0][j] = f[p][0][i][k][j], g[1][0][j] = f[p][1][i][k][j];lep(dl, 1, n - i) {lep(j, 0, m) {upa(g[a[d]][dl][j + dl - 1], mod - g[0][dl - 1][j]);upa(g[a[d]][dl][j + dl + k - 1], g[0][dl - 1][j]);upa(g[a[d] ^ 1][dl][j + dl - 1], mod - g[1][dl - 1][j]);upa(g[a[d] ^ 1][dl][j + dl + k - 1], g[1][dl - 1][j]);}}lep(dl, 1, n - i) lep(j, 0, m) upa(f[p ^ 1][0][i + dl][dl][j], mul(C[i + dl - 1][dl], g[0][dl][j])),upa(f[p ^ 1][1][i + dl][dl][j], mul(C[i + dl - 1][dl], g[1][dl][j]));}p ^= 1;lep(k, 1, n) lep(j, n - 1, m) {rep(t, j, n - 1)upa(ans[t], mul(f[p][1][n][k][j], C[j][t]));}}lep(i, n - 1, m) std::cout << (ans[i] + mod) % mod << ' ';std::cout << '\n';#ifdef DEBUGstd::cerr << clock() - c1 << " ms " << fabs(&ENDPOS - &FIRPOS) / 1024 / 1024 << " MB\n";
#endifreturn 0;
}

B.

容易发现操作 lowbit(n) 即可,不能这样操作则必败。

证明参考 Link (作者懒得证了,不保证引用文章正确)

C.

对序列求逆,变成排序问题。

定义两个基本操作,将 \(n\)\(n-1\) 交换,将 \([1, n - 1]\) 向右循环一维。

这样我们就可以进行排序了。

具体的,如果 \(n\) 的位置是 \(n\) ,则随便找一个位置尚未确定的数放在 \(n\) 这个位置上。

否则,以 \(1\) 作为基准,直接将前面的序列循环移位若干次,使得交换之后末位数相对位置正确。

使用倍增加快这个过程,操作期望 \(O(n\log^2 n)\)

点击查看

#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = a; i <= b; ++i)
#define rep(i, a, b) for (int i = a; i >= b; --i)
#define il inline
#define cmx(a, b) ((a) > (b) ? (a) : (b))
#define cmn(a, b) ((a) < (b) ? (a) : (b))
#define gmx(a, b) a = cmx(a, b)
#define gmn(a, b) a = cmn(a, b)template <typename T>
void _debug(const T& t) { std::cerr << t << '\n'; }
template <typename T, typename... Args>
void _debug(const T& t, const Args&...res) { std::cerr << t << ' '; _debug(res...); }
#define debug(...) _debug(#__VA_ARGS__ " =", __VA_ARGS__)const int LN = 2e5 + 7;
typedef long long ll;
typedef std::vector <int> vec ;
typedef std::pair<int, int> PII;const int M = 6;
vec jump[6]; int len[M + 1] = { 0, 1, 4, 16, 64, 256, 700 };
std::vector <vec> perm(int n) { std::vector <vec> ans;jump[0].resize(n);lep(i, 0, n - 1) jump[0][i] = i;std::swap(jump[0][n - 1], jump[0][n - 2]);int d = 0;lep(i, 1, M) {d = len[i]; if (d >= n) break;jump[i].resize(n), jump[i][n - 1] = n - 1;lep(k, 0, n - 2) jump[i][k] = (n - 1 + k - d) % (n - 1);}lep(i, 0, M) if (jump[i].size()) ans.emplace_back(jump[i]); else break;return ans;
}int t[2][LN], op, n, c[LN], ans[LN];
int cnt = 0; std::bitset <LN> st;
il void work(int p) {lep(i, 0, n - 1) t[op ^ 1][i] = t[op][jump[p][i]], c[t[op ^ 1][i]] = i;ans[cnt++] = p, op ^= 1;
}
vec cons(vec p) { cnt = op = 0; int x;n = p.size(), st.set(), st.reset(0);lep(i, 0, n - 1) c[i] = p[i], t[op][c[i]] = i;if (c[0] == n - 1) work(0);lep(i, 1, n - 2) {if (t[op][n - 1] == n - 1) {x = n - 2 - c[st._Find_first()], --i;rep(j, M, 1) lep(k, 0, 4) if (len[j] <= x) x -= len[j], work(j);work(0);} else {x = n - 2 - (c[0] + t[op][n - 1]) % (n - 1), st.reset(t[op][n - 1]);rep(j, M, 1) lep(k, 0, 4) if (len[j] <= x) x -= len[j], work(j);work(0);}}if (c[0] != n - 1) {x = n - 1 - c[0];rep(j, M, 1) lep(k, 0, 4) if (len[j] <= x) x -= len[j], work(j);}vec t(cnt); lep(i, 0, cnt - 1) t[i] = ans[i];return t;
}

D.

将有自环就无解判掉。

可以证明的是,颜色最多两种,\(u<v\)\(u>v\) 各染一种就合法。

字典序考虑贪心,依次考虑边 \(u\rightarrow v\) ,如果 \(v\) 本来可以到 \(u\) ,将次边标记为 \(2\) ,否则加入这条边,标记为 \(1\)

正确性考虑一条边 \((u, v)\) 被染成 \(2\) ,那么在 \(1\) 组成的 DAG 上 \(u\) 的拓扑序大于 \(v\) ,所以 \(2\) 边组成的图仍然是 DAG。

如果维护连通性呢?很难维护就考虑上根号。

\(\sqrt n\) 次操作为一组,需要考虑 \(O(\sqrt n)\) 对边之间的可达性,提前 bitset 预处理。

直接模拟,加边就把所有的关键点扫描一遍更新。

复杂度 \(O(n\sqrt n)\)

点击查看

#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = a; i <= b; ++i)
#define rep(i, a, b) for (int i = a; i >= b; --i)
#define il inline
#define cmx(a, b) ((a) > (b) ? (a) : (b))
#define cmn(a, b) ((a) < (b) ? (a) : (b))
#define gmx(a, b) a = cmx(a, b)
#define gmn(a, b) a = cmn(a, b)template <typename T>
void _debug(const T& t) { std::cerr << t << '\n'; }
template <typename T, typename... Args>
void _debug(const T& t, const Args&...res) { std::cerr << t << ' '; _debug(res...); }
#define debug(...) _debug(#__VA_ARGS__ " =", __VA_ARGS__)const int LN = 1e5 + 7;
const int LM = 600 + 7;
typedef long long ll;
typedef std::pair<int, int> PII;bool FIRPOS;int n, m, u[LN], v[LN], B, id[LN], stk[LN], tot;
std::bitset <LM> to[LN];
std::bitset <LN> ans, vis;
std::vector <int> e[LN];bool ENDPOS;void dfs(int u) {if (vis[u]) return; vis[u] = true;if (id[u]) to[u].set(id[u]);for (int v : e[u]) dfs(v), to[u] = to[u] | to[v];
}
void solve(int l, int r) { tot = 0;lep(i, l, r) {if (!id[u[i]]) id[u[i]] = ++tot, stk[tot] = u[i];if (!id[v[i]]) id[v[i]] = ++tot, stk[tot] = v[i];}lep(i, 1, n) if (id[i]) dfs(i);lep(i, l, r) {if (to[v[i]][id[u[i]]]) { ans.set(i); continue; }e[u[i]].push_back(v[i]);lep(j, 1, tot) if (to[stk[j]][id[u[i]]]) to[stk[j]] |= to[v[i]];}lep(i, 1, n) id[i] = 0, to[i].reset(); vis.reset();
}int main() {std::ios::sync_with_stdio(false),std::cin.tie(nullptr), std::cout.tie(nullptr);int c1 = clock();std::cin >> n >> m; B = 300;lep(i, 1, m) {std::cin >> u[i] >> v[i];if (u[i] == v[i]) { std::cout << "-1\n"; return 0; }}int l = 0;lep(i, 1, m) if (i == m or i - l == B) solve(l + 1, i), l = i;lep(i, 1, m) std::cout << (ans[i] + 1) << ' ';std::cout << '\n';#ifdef DEBUGstd::cerr << clock() - c1 << " ms " << fabs(&ENDPOS - &FIRPOS) / 1024 / 1024 << " MB\n";
#endifreturn 0;
}

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

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

相关文章

网站建设与设计毕业设计西安加盟代理网站建设

转自&#xff1a;http://xilinx.eetrend.com/content/2019/100042384.html xilinx7系列FPGA主要包括&#xff1a;Spartan-7、Artix-7、Kintex-7、Virtex-7。其性能/密度/价格也随着系列的不同而提升。 Spartan7系列是7系列中的屌丝青年&#xff0c;拥有最低的价格、最低的功耗…

UNIQUE VISION Programming Contest 2024 Autumn (AtCoder Beginner Contest 425)

A - Sigma Cubes点击查看代码 #include <bits/stdc++.h>using i64 = long long;void solve() {int n;std::cin >> n;int ans = 0;for (int i = 1; i <= n; ++ i) {ans += (i % 2 ? -1 : 1) * i * i * …

WPF Canvas draw circle,triangle,rectangle such as mark

//Window.xaml <Window x:Class="WpfApp15.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quo…

论文解读-《Less is More on the Over-Globalizing Problem in Graph Transformers》 - zhang

1. 论文介绍 论文题目:Less is More on the Over-Globalizing Problem in Graph Transformers 论文领域:图神经网络,graph transformer 论文发表: ICML 2024 论文代码:https://github.com/null-xyj/CoBFormer 论文…

发布软文网站济南建设工程交易中心

在互联网的世界中&#xff0c;不同应用程序的数据传输方法各异。P2P文件共享&#xff08;Peer-to-Peer File Sharing&#xff09; 作为一种高效的文件传输方式&#xff0c;使得用户可以在没有中央服务器的情况下直接进行文件交换。本文将详细介绍P2P文件共享的基本原理、优势及…

网站规范建设学校网站集群建设

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:Hash索引和B+树区别是什么?在设计索引怎么选择? 在MySQL中,Hash索引和B+树索引是两种常见的索引类型,他们有以下区别: 数据结构:Hash索引:…

loguru 日志库快速入门

1.loguru 1.1 loguru 介绍loguru是一个功能强大且非常容易使用的第三方开源Python日志管理库。它建立在Python标准库中的logging模块之上,并提供了更加简洁直观、功能丰富的接口。github仓库地址:https://github.com…

MATLAB工具箱

MATLAB工具箱一、一维离散数据微分、积分求解 1. 离散积分 function result = integral(x,y,c)result = [];for i=1:1:length(y)c=y(i)*(x(2)-x(1))+c ; result(end+1) = c;end end2. 离散微分 function result = diff…

内存访问流程

*假设执行 int a=0x1234(分配一块逻辑地址,0x56789999)32位系统 *CPU会将逻辑地址拆分为两部分 V=56789() 页内偏移=0x999 *由MMU使用0x56789变量,查进程表找到值为0xabcde *拼接物理地址:0xabcde 999 *有内存…

网站推广洛阳wordpress插件中文版下载

C# 中的字符串类型&#xff08;string&#xff09;是不可变的&#xff0c;这意味着一旦创建了一个字符串对象&#xff0c;就不能再对其进行修改。 当对一个字符串进行拼接、替换、删除等操作时&#xff0c;实际上是创建了一个新的字符串对象&#xff0c;而原始的字符串对象保持…

.NET操作Word实现智能文档处理 - 内容查找替换与书签操作

如何在Word大量文档中查找并替换特定内容?如何在文档的特定位置自动插入动态内容?如何创建能够自动生成报告的智能文档系统?本文介绍的查找替换和书签操作技术,将能够轻松实现这些功能,大大提高文档处理的效率和准…

day19_添加 修改

day19_添加 修改 1添加场景分析1使用弹出框 承载添加界面 2弹出框输入菜单信息 提交到添加接口 3添加接口处理完毕 反馈信息 弹窗处理结果 关闭弹出框 刷新table数据 2sql分析 -- 逻辑主键 一般不加自增 由使用人员维…

day18_查询功能 合并servlet

day18_查询功能 合并servlet 1.sql分析 -- 分页+条件 查询 select am1.*,IFNULL(am2.menuname,无) as pname from admin_menu am1 left join admin_menu am2 on am1.pid = am2.mid-- 动态查询条件 where am1.menuna…

NOIP模拟赛 十七

倍增+DP+DP+可持久化平衡树A. 对于一个 \(x\) ,如果 \(x\bmod a < x\) ,称其为有效的。我们断言,有效次取模只会发生 \(\log\) 次。 如果发生有效取模,则 \(a<x\) 。\(a\le \frac{x}{2}\) 则 \(x\bmod a <…

day22_用户模块

day22_用户模块 1查询sql分析 -- 定制系统 -- 查询分段记录 select au1.*,au2.username create_uname from admin_user au1 left join admin_user au2 on au1.create_uid = au2.uidwhere au1.username like CONCAT(%,a…

做招聘网站多少钱网站找不到首页

一切从“/”开始 在Linux系统中&#xff0c;目录、字符设备、块设备、套接字、打印机等都被抽象成了文件&#xff0c;一切皆为件 与windows操作系统不同&#xff0c;Linux系统内不存在C/D/E/F盘等&#xff0c;一切文件都是从根&#xff08;/&#xff09;目录开始的 Linux系统…

常州网站建设要多少钱wordpress 全站ajax

随着物联网、大数据、人工智能等技术的快速发展&#xff0c;边缘计算已成为当前信息技术领域的一个热门话题。在物联网领域&#xff0c;边缘计算被广泛应用于智慧交通、智能安防、工业等多个领域。因此&#xff0c;基于边缘计算技术的工业主板设计方案也受到越来越多人的关注。…

2025 丹东店推荐:丽格门窗,用 20 年技术沉淀守护家的舒适

在四季分明、冬季严寒的丹东,门窗的隔热保温、密封抗风性能直接决定着家居生活的幸福感。2025 年装修选门窗,坐落于丹东市振兴区兴六路大昌建材隔壁的丽格门窗店,带来了专为北方气候定制的系统门窗解决方案,其深厚…

NOIP2025模拟赛23

T1 T2 T3 T4\(\color{#52C41A} 普及+/提高\) \(\color{#3498DB} 提高+/省选-\) \(\color{#52C41A} 普及+/提高\) \(\color{#9D3DCF} 省选/NOI-\)参赛网址:https://oj.33dai.cn/d/TYOI/contest/689d2670c5d9c2f14c2250…

step

action被输入到机器人的控制器之前,做一个预处理,做一个clip截断,乘以一个scale,做完之后,再apply到机器人,计算reward和done(超时或者terminate),有done就reset,apply interval event,最后计算观测。 acti…