Edu38

1|0基本情况

C又不是正解,A甚至还加一,以后要考虑好再交。

2|0C. Constructing Tests

Problem - C - Codeforces

为了更好的代码实现而非手算出解来推式子

式子都推出来了。

n2nm2=x

2|1myCode

不知道怎么直接解,就写了一个 O(nlogn) 的枚举 m 然后对 n 二分的写法。

constexpr int N(1E9 + 1); void solve() { #define tests int x; std::cin >> x; if (x == 0) { std::cout << "1 1\n"; return ; } for (int m = 1; m * m <= x * 10; m++) { i64 lo(m), hi(N); auto check = [&](auto& o) -> bool { return o * o - (o / m) * (o / m) < x; }; i64 n(0); while (lo <= hi) { i64 mid(lo + hi >> 1); if (check(mid)) { lo = mid + 1; } else { hi = mid - 1; n = mid; } } if (n * n - (n / m) * (n / m) == x) { std::cout << n << ' ' << m << '\n'; return ; } } error; }

2|2STD

我疑惑的点在于如果按照求根公式那一套来解,代码很难实现,而且还要考虑下取整。

实际上可以暴力一点,先因式分解一下(为了方便代码实现服务)

(n+nm)(nnm)=x

x1=(n+nm)

x2=(nnm)

然后直接 O(x) 枚举 x1,x2

然后通过 x1,x2,解出 n,m(暂时不用管向下取整等等)

最后再回代验证,就确保了正确性。

void solve() { #define tests int x; std::cin >> x; if (x == 0) { std::cout << "1 1\n"; return ; } for (int i = 1; i * i < x; i++) if (x % i == 0) { int x_1(x / i), x_2(i); int n(x_1 + x_2 / 2), m((x_1 + x_2) / (x_1 - x_2)); if (n * n - (n / m) * (n / m) == x) {//回代验证 std::cout << n << ' ' << m << '\n'; return ; } } error ; return ; }

3|0D. Buy a Ticket

Problem - D - Codeforces

建图技巧:虚点

化点权为边权

暴力的想法是对每一个点跑单源最短路,肯定超时。

考虑优化,因为每条路径最后一定会加上 aj,也就是终点的点权,我们直接建立一个虚点,对所有城市连边,其边权就是每个城市的点权。

然后直接从虚点出发跑一次单源最短路,自然就得到了所有点的最短路径(从终点到起点的)。

struct Node { i64 v; i64 w; }; struct State{ i64 u, d; bool operator < (const State &s) const { return d > s.d; } }; int n, m; std::vector<std::vector<Node>> adj; std::vector<i64> dis; void dijkstra(int S){ std::priority_queue<State> heap; dis.assign(n + 1, LONG_LONG_MAX); heap.push({S, 0}); dis[S] = 0; while(not heap.empty()){ auto[u, d](heap.top()); heap.pop(); if (d > dis[u]) continue; for (auto&[v, w] : adj[u]) { if (dis[u] + w < dis[v]) { dis[v] = dis[u] + w; heap.push({v, dis[v]}); } } } } void solve() { std::cin >> n >> m; adj.assign(n + 1, std::vector<Node>()); for (i64 i = 0, u, v, w; i < m; i++) { std::cin >> u >> v >> w; adj[u].push_back({v, w * 2}); adj[v].push_back({u, w * 2}); } for (int i = 1; i <= n; i++) { i64 w; std::cin >> w; adj[0].push_back({i, w}); } dijkstra(0); for (int i = 1; i <= n; i++) { std::cout << dis[i] << ' '; } std::cout << '\n'; }

4|0E. Max History

Problem - E - Codeforces

对于一个 n 的排列 a1,a2,,an。对于 i (从小到大枚举),如果 ai>aj,则:k=1i1ak。对 n 种可能的排列的 k=1nakmod109+7

推式子

首先,由于总共 n! 种排列的 f(a) 难以分每次逐个统计,于是想到对每一个以 ai 为终值的排列对答案的贡献分开计算并且求和。

而注意到,当 am>ai 时,m=i,由此可以得知:

如果将历史上出现的每一个 am 的值组成一个序列,则这个序列是单调递增的。

am0 变为终值的过程中,只与那些比 am 小的数有关

考虑先进行排序(时限3s),通过一次扫描对每个 ai 得到比其值小的数字个数 prei

下面就到式子了:

假设对于 ai ,共有 x​ 个数比其小。

因为只有ai 前的比起小的数会对结果有影响,故考虑枚举 ai 前比其小的数字个数

假设当前 ai 前面有 i 个比它小的数,共 (xi) 种方案。

i 个数随便排列,共 i! 种方案。

剩下除这 i 个数与当前枚举的 ai 以外的数共 ni1 个随意排列方案数:(ni1)!

所以数 ai 对答案的贡献次数为:

i=0x(xi)·i!·(ni1)!

下面的过程是简化这个式子:

拆组合数:

=i=0xx!i!·(xi)!·i!·(ni1)!

抵消:

=i=0xx!(xi)!·(ni1)!

x! 提到前面:

=x!·i=0x(ni1)!(xi)!

由组合数:(nm)=n!m!(nm)! 添项:

=x!·i=0x(ni1)!(xi)!(nx1)!·(nx1)!

(nx1)! 提到前面:

=x!·(nx1)!·i=0x(ni1)!(xi)!(nx1)!

合成组合数:

=x!·(nx1)!·i=0x(n1ixi)

由于 ixi 值域均为 0x,且(i)+(xi)=x

所以 ixi 可相互替换(相当于求和的循环倒着枚举):

=x!·(nx1)!·i=0x(n1x+ii)

=x!·(nx1)!·i=0x(nx+i1i)

又因为:i=0k(n+i1i)=(n+kk)这一步利用了上项求和,关键在于多加了一项(n1)=0

=x!·(nx1)!·(nx)

拆组合数:

=x!·(nx1)!·n!x!(nx)!

抵消:

=n!·(nx1)!(nx)!

=n!nx

因为最终值 am 不会被计算在答案当中,显然排序后所有值为 an 的数不应该被统计在答案当中。

则答案就为:

i=1nn!nprei·ai·[aian]

void solve() { int n; std::cin >> n; std::vector<int> pre(n), a(n); for (auto& x : a) std::cin >> x; std::sort(all(a)); for (int i = 0; i + 1 < n; i++) { if (a[i + 1] == a[i]) { pre[i + 1] = pre[i]; } else { pre[i + 1] = i + 1; } } Z ans(0); Z fac(comb.fac(n)); for (int i = 0; i < n; i++) { if (a[i] == a[n - 1]) { break; } ans += fac / (Z(n) - Z(pre[i])) * Z(a[i]); } std::cout << ans << '\n'; }

另外一种推式子,更简洁


__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/18086145.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示