CF848E Days of Floral Colours 题解

Problem - 848E - Codeforces

首先,由于整个图是对称的,所以我们将其沿直径分为两半,在算一半答案时把每一段的贡献平方再相加即可。(因为对面也有一段相同长度的也要计入贡献)

现在我们的问题转化为了对于一个长为 \(n\) 的环,你可以给一个点连出一个线头(即在原图中连向对面的边)将其余点进行配对,每一对的距离不能超过 \(2\)。求总权值和。

对于环上问题,我们先破环为链,我们若随机指定一个点作为破开的起点则可能出现一段甚至一个配对横跨首尾的情况,不可取。我们选择指定一个线头,枚举线头向后一段的长度,最终再乘上这个贡献即可。

现在我们需要考虑一个序列问题:对于每个 \(n\) ,求一个长为 \(n\) 的序列,在上面留线头或者配对的总权值和。

由于要求出每个 \(n\) 的答案,考虑 DP。

为了方便计算,我们先不管线头,先算出来一个长为 \(n\) 的配对方案数,记为 \(x_n\)

对于一个状态,我们可以向后放一个长度为 \(1\) 的配对或者两个长度为 \(2\) 的配对交叉起来,所以:

\[x_n=x_{n-2}+x_{n-4} \]

好了,现在进入本题的核心。


我们发现我们上面所考虑的序列问题是不严谨的。

因为可能左侧和右侧会伸出去一个长度为 \(2\) 的配对,这一点在破环为链中很重要,因为计算答案的系数不同。

所以我们现在需要计算一个序列向左右都不伸出去配对,向左伸出 \(1\) 个配对和左右都伸出配对的权值和。(向左和向右对称)

我们分别记他们为 \(f_n,g_n,h_n\)

接下来开始暴力推式子环节,推式子的过程本身小学生都可以完成,这里不放一坨坨 \(\LaTeX\) 了。

结论:

\[f_n=(n-1)^2x_{n-1}+\sum_{i=1}^{n-1}f_{n-i}(i-1)^2x_{i-1}+\sum_{i=2}^{n-2}g_{n-i}(i-1)^2x_{i-2} \\ g_n=(n-1)^2x_{n-2}+\sum_{i=1}^{n-1}f_{n-i}(i-1)^2x_{i-2}+\sum_{i=2}^{n-2}g_{n-i}(i-1)^2x_{i-3} \\ h_n=(n-1)^2x_{n-3}+\sum_{i=1}^{n-2}g_{n-i}(i-1)^2x_{i-2}+\sum_{i=2}^{n-3}h_{n-i}(i-1)^2x_{i-3} \\ \]

很好,现在我们已经做完了

我们发现这个式子直接进行递推是 \(\Theta(n^2)\) 的,显然无法通过此题。

但是我们注意到对于每个 \(i\) 的系数在对应的方程位置里是固定的。

我们使用分治 FFT 进行计算即可。


实现细节:

可以设立一个 update 函数进行计算一个式子对后面的贡献,利用另外三个数组来表示转移方程中的系数,即可优雅地实现这个原本代码实现难度相当高的题目。

详细看代码。

/** @Author: LightningCreeper l_ghtn_ngcr__p_r@outlook.com* @Date: 2024-12-30 21:01:12* @LastEditors: LightningCreeper l_ghtn_ngcr__p_r@outlook.com* @LastEditTime: 2024-12-30 21:46:22* @FilePath: /i.省队训练/C.cpp* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE*/
#include <bits/stdc++.h>
#pragma GCC optimize(3, 2, 1, "Ofast")
using namespace std;#define int long long
#define endl '\n'
#define debug(x) cerr << #x << " = " << x << endl
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define per(i, a, b) for (int i = (a); i >= (b); i--)
#define gn(u, v) for (int v : G.G[u])
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define pii pair<int, int>
#define vi vector<int>
#define vpii vector<pii>
#define vvi vector<vi>
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define tomin(x, y) ((x) = min((x), (y)))
#define tomax(x, y) ((x) = max((x), (y)))
#define ck(mask, i) (((mask) >> (i)) & 1)
#define pq priority_queue
#define FLG (cerr << "Alive!" << endl);constexpr int MAXN = 2e5 + 5;constexpr int MOD = 998244353;
constexpr int G = 3;
constexpr int GINV = 332748118;int qpow(int x, int y) {int ans = 1;while (y) {if (y & 1)ans = ans * x % MOD;x = x * x % MOD;y >>= 1;}return ans;
}int rt[MAXN];void NTT(int x[], int len, bool t) {for (int i = 0; i < len; i++)if (i < rt[i])swap(x[i], x[rt[i]]);for (int i = 1; i < len; i *= 2) {int n;if (t)n = G;elsen = GINV;n = qpow(n, (MOD - 1) / (i * 2));for (int j = 0; j < len; j += (i * 2)) {for (int k = 0, t = 1; k < i; k++, t = (t * n) % MOD) {int p = x[j + k];int q = t * x[j + k + i] % MOD;x[j + k] = (p + q);x[j + k + i] = p - q + MOD;if (x[j + k] >= MOD)x[j + k] -= MOD;if (x[j + k + i] >= MOD)x[j + k + i] -= MOD;}}}
}void Times(int a[], int b[], int len) {int l = __lg(len);for (int i = 0; i < len; i++)rt[i] = 0;for (int i = 0; i < len; i++)rt[i] = (rt[i >> 1] >> 1) | ((i & 1) << (l - 1));NTT(a, len, true);NTT(b, len, true);for (int i = 0; i < len; i++)a[i] = a[i] * b[i] % MOD;NTT(a, len, false);NTT(b, len, false);int inv = qpow(len, MOD - 2);for (int i = 0; i < len; i++) {a[i] = a[i] * inv % MOD;b[i] = b[i] * inv % MOD;}
}int n;
int tmp[MAXN], f0[MAXN], g0[MAXN], f1[MAXN], g1[MAXN], f2[MAXN], g2[MAXN], g[MAXN];void update(int f[], int g[], int h[], int len) { // f = gh, h on the leftfor (int i = 0; i < len * 2; i++)tmp[i] = 0;for (int i = 0; i < len / 2; i++)tmp[i] = h[i];Times(tmp, g, len * 2);for (int i = len / 2; i < len; i++)(f[i] += tmp[i]) %= MOD;
}void CDQ(int l, int r) {if (l + 1 == r) {(f0[l] += g0[l]) %= MOD;(f1[l] += g1[l]) %= MOD;(f2[l] += g2[l]) %= MOD;return;}int mid = l + r >> 1;int len = r - l;CDQ(l, mid);update(f0 + l, g0, f0 + l, len);update(f0 + l, g1, f1 + l, len);update(f1 + l, g1, f0 + l, len);update(f1 + l, g2, f1 + l, len);update(f2 + l, g1, f1 + l, len);update(f2 + l, g2, f2 + l, len);CDQ(mid, r);
}signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n;g[0] = g[2] = 1;for (int i = 4; i <= n; ++i)g[i] = (g[i - 2] + g[i - 4]) % MOD;for (int i = 1; i <= n; ++i)g0[i] = (i - 1) * (i - 1) * g[i - 1] % MOD;for (int i = 2; i <= n; ++i)g1[i] = (i - 1) * (i - 1) * g[i - 2] % MOD;for (int i = 3; i <= n; ++i)g2[i] = (i - 1) * (i - 1) * g[i - 3] % MOD;int len = (1 << (__lg(n) + 1));CDQ(0, len);// FLGint ans = n * (g0[n] + g2[n]) % MOD;for (int i = 2; i < n - 1; i++)(ans += i * (g0[i] * f0[n - i] % MOD + 2 * g1[i] * f1[n - i] % MOD + g2[i] * f2[n - i] % MOD) % MOD) %= MOD;cout << ans << endl;return 0;
}

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

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

相关文章

vmware下载安装配置

vmware下载安装配置 下载 https://www.vmware.com/ # 官网 https://www.broadcom.com/ # Broadcom官网 https://www.vmware.com/products/desktop-hypervisor/workstation-and-fusion # VMware官网虚拟机下载页 https://www.filehorse.com/download-v…

软件安全测试

一、网络协议基础 1、网络模型 我们把一些过程封装到一起,称为“模型”,如下:把北京中的4个步骤封装到一起,就是1个模型了。 (1)网络模型-OSI OSl(Open System Interconnection 开放系统互联)参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体…

开拓计划21/2025集训作业表3 - 倍增ST表LCA次小生成树

开拓计划21/2025集训作业表3 - 倍增&ST表&LCA&次小生成树 倍增&ST表 概念Q:倍增是什么? A:倍增,顾名思义是成倍增长的意思,它利用了二进制的性质和预处理(俗称打表)的思想,在 \(O(\log n)\) 内完成一些操作。 Q:ST表是什么? A:ST表主要用于解决RMQ(…

系统管理体系之进程管理

系统管理体系之进程管理 1. 进程名字 含义程序 安装包,程序代码,app,存放在磁盘上面.进程⭐️ 运行起来的程序,命令,服务(远程连接服务,网络服务)都可以称作进程。 运行在内存中。守护进程 守护进程, 一直运行的进程. 也可以叫做服务.2. 进程分类(异常进程) 2.1 僵尸进程⭐️⭐…

系统管理之服务管理---管理命令

1. 系统管理之服务管理---管理命令systemctl 管理服务开机自启动管理正在运行的服务.旧版本的系统:Centos 5.x 6.x 需要使用service 命令检查 sshd 远程连接服务状态systemctl status sshd systemctl status 单个或多个服务名如何设置开启开机自启动 systemctl enable sshd 当…

夜之向日葵

2024 ECF 游记 Day 0 我早就预感到 ecf 要寄,但没想到寄得这么彻底。 比赛之前,我去做了去年 ecf 的题目,发现里面的可做题全部都是贪心,性质和结论题。众所周知,chino 最不擅长的题目类型就是这些。 同时,因为周一周二要考大物和数分,比赛前的一周几乎没有训练。 于是就…

网络流初步

网络流初步(脑部整理) 呜呜呜,家人们也是学上网络流了。 咸鱼起手,你反应得过来吗? 英语不太好(老英不会看窝博客吧) What is 网络流?概述 网络\((network)\)是指一个特殊的有向图 \(G=(V,E)\),其与一般有向图的不同之处在于有容量和源汇点。$E $中的每条边 $ (u, v)$ 都…

金砖技能大赛-内存取证

检材链接 :https://pan.baidu.com/s/1tYgIicCqJExmaMLYa3YeSA 提取码:lulu按照惯例先打印出信息 1.从内存中获取到用户admin的密码并且破解密码,以Flag{admin,password} 形式提交(密码为 6 位); 先使用lsadump指令看看python2 vol.py -f /文件路径/文件 hashdump最后一个是…

script 标签放在 HTML 文档的 body 内底部

以下是将 <script> 标签放在 HTML 文档的 <body> 内底部的几个重要原因: 1. 页面加载顺序和性能优化原理:当浏览器解析 HTML 文档时,它会按顺序执行遇到的元素。如果 <script> 标签位于 <head> 中或 <body> 的顶部,浏览器会在下载和执行脚本…

折腾笔记[4]-cuda的hello-world

在window11上搭建cuda开发环境并编译hello world程序;摘要 在window11上搭建cuda开发环境并编译hello world程序; 关键信息编译器:cuda nvcc 12.4.131 平台:windows11原理简介 cuda简介 CUDA(Compute Unified Device Architecture,统一计算架构)是由英伟达所推出的一种集成技术…

13. 滑块控件

一、抽象滑块QScrollBar、QSlider 和 QDail 都是从 QAbstractSlider 类继承而来的,因此它们的多数方法是相同的。我们可以在终端中使用 pip 安装 pyside6 模块。 pip install pyside6QAbstractSlider 类的常用方法如下: # 实例方法 orientation() -> Qt.Orientation …

3.数据类型

3.1字符串1.正常字符串使用 或 "" 包裹起来2.注意转义字符 \ \ 显示’ \n 换行 \t tab \u4e2d \u### Unicode字符3.多行字符串编写 4.模板字符串5.字符串长度 str(变量名).length6.字符串的可变性,不可变String Buffer和StringBuilder都是可变的,String…