P10259 [COCI 2023/2024 #5] Piratski kod

news/2025/10/28 20:57:39/文章来源:https://www.cnblogs.com/flvwfv/p/19172678

题链

题意

首先,题目写的很抽象,模拟赛时读了半个小时才读懂

题意概括一下就是枚举长度为k的所有01串

然后对01串进行划分,每遇到两个1就进行一次划分

然后把每段提取出来单独处理

如果把提出来的01串计为\(s[1...r]\)

则改01串的价值为\(\sum_{i=1}^{r-1}s[i]*f[i+1]\)

其中f数组为斐波那契数列,\(f[1]=1\),\(f[2]=1\),然后递推即可

最后分别输出长度为\(k\)的01串价值和,不同k之间独立,\({k=1,2...n}\)

Solution

我们现在处理长度为k的01串,我们已经知道了前一个的答案

考虑这个k无非是在长度为k-1的每个串后面加上0/1构成的

那么,我们考虑,我们如果加上一个0,贡献是不会变的,是一个ans[k-1]

如果我们加上一个1,会有什么变化呢?

会使原本最后一段没有贡献,且末尾为1的产生贡献

那么现在我们就可以转移了

我们先无脑处理出来几个数组

\({fa_{i,0/1}},dp_{i,0/1},fx_{i}\)

\({fa_{i,0/1}}\)表示长度为i,结尾是0/1,中间没有连续1的方案数

\({dp_{i,0/1}}\)表示长度为i,结尾是0/1,中间没有连续1的贡献,注意:包括最后一个1

\({fx_{i}}\)表示长度为i,以1结尾且结尾开始到前面第一个0的长度为偶数的数量

转移式子很简单

\(fa_{i,0}=fa_{i-1,0}+fa_{i-1,1},fa_{i,1}=fa{i-1,0}\)

\({dp_{i,0}=dp_{i-1,0}+dp_{i-1,1}},dp_{i,1}=dp_{i-1,0}+fa_{i-1,0}*f_{i+1}\)

\(fx_{i}=\sum_{j=2}^{j+=2,j<i}2^{i-j-1}+!(i\)%\(2)\)

然后答案就很简单了

\(ans_i=\sum_{j=1}^{i-2}dp_{j,1}*fx_{i-j-1}+dp_{i-1,1}+ans_{i-1}*2\)

\({\sum_{j=1}^{i-2}dp_{j,1}*fx_{i-j-1}+dp_{i-1,1}}\)这个是枚举最后一段区间的长度为{j}时的贡献

最后输出即可

也是非常简单

/*ILVWYT*/#include<bits/stdc++.h>
#define in :
#define int __int128
#define IfFast
using namespace std;namespace fast {
#ifdef IfFastvoid read(int &a) {int s = 0, f = 1;char ch = getchar();while (!(ch <= '9' && ch >= '0')) {if (ch == '-') {f = -1;}ch = getchar();}while (ch <= '9' && ch >= '0') {s = s * 10 + ch - '0';ch = getchar();}a = s * f;return void();}void read(char &a) {char x = getchar();while (x == ' ' || x == '\r' || x == '\n' || x == '\t') {x = getchar();}a = x;return void();}void print(int x) {if (x < 0) {putchar('-');x = -x;}if (x < 10) {putchar(x + '0');} else {print(x / 10);putchar(x % 10 + '0');}return void();}
#endiftemplate<typename T>void read(T &a) {cin >> a;return void();}template<typename T, typename... Args>void read(T &a, Args &... args) {read(a);read(args...);return void();}inline int read() {int a;read(a);return a;}template<typename T>void print(T a) {cout << a;return void();}template<typename T, typename... Args>void print(T a, Args... args) {print(a);print(args...);return void();}
}using fast::read;
using fast::print;
using us = unsigned;
constexpr int mod = 1e9 + 7;
constexpr int N = 10000;
int n;
int f[N + 20];
int ans[N + 10];
int dp[N + 10][2]; //长度为n的,以1/0结尾的,没有连续1的贡献
int fa[N + 10][2];inline int quick(int x,int y) {int ans = 1;while (y) {if (y & 1) {ans *= x;ans %= mod;}x *= x;x %= mod;y >>= 1;}return ans;
}int fx[N + 10]; //长度为n,结尾1的个数还是偶数的方案数signed main() {
#ifndef IfFastios::sync_with_stdio(false);
#endifread(n);f[1] = 1;f[2] = 1;for (us i = 3; i <= n + 10; i++) {f[i] = f[i - 1] + f[i - 2];f[i] %= mod;}dp[1][1] = 1;fa[1][1] = 1;fa[1][0] = 1;for (us i = 2; i <= n; i++) {fa[i][1] = fa[i - 1][0];fa[i][0] = fa[i - 1][0] + fa[i - 1][1];fa[i][0] %= mod;fa[i][1] %= mod;dp[i][0] = dp[i - 1][0] + dp[i - 1][1];dp[i][1] = dp[i - 1][0] + fa[i - 1][0] * f[i + 1] % mod;dp[i][0] %= mod;dp[i][1] %= mod;if (i % 2) {for (us j = 2; j < i; j += 2) {fx[i] += quick(2, i - 1 - j) % mod;fx[i] %= mod;}} else {for (us j = 2; j < i; j += 2) {fx[i] += quick(2, i - 1 - j) % mod;fx[i] %= mod;}fx[i]++;fx[i] %= mod;}}// print(fx[3], ' ', fx[4], '\n');ans[2] = 1;ans[3] = 4;fx[0] = 1;for (us i = 3; i <= n; i++) {ans[i] = ans[i - 1] * 2 % mod;for (us j = 1; j < i - 2; j++) {const int ws = i - j - 1;ans[i] += dp[j][1] * fx[ws] % mod;ans[i] %= mod;}ans[i] += dp[i - 1][1];ans[i] %= mod;}for (us i = 1; i <= n; i++) {print(ans[i], ' ');}return 0;
}

还有开int128,不然会wa(本地跑很对)

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

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

相关文章

巧用 using 作用域(IDisposable)的生命周期包装特性 实现前后置处理

需求:在多个方法前后输出日志 logger.Info("begin"); method(); logger.Info("end");如果需要在方法后输出日志同时加上时长 logger.Info("begin"); var sw= Stopwatch.StartNew(); me…

2025.10.27训练记录

其实是10.28晚上写的。感觉就这个题要记录一下。 上午noip模拟。喜提一道不会。 B 题外话: 7:45 开始考试,广附集训爷大吼一声我做过!声称A完全不可做,但B他场切了。于是我开场看B。 那就看B,7:50闭了一下眼睛,睁…

软考复习总结

距离软考还有不到十天,主要对学习的知识点进行总结回顾(以下知识点无顺序重点): 1.对于尾数用补码进行表示时,要注意如果机器位8位,已知补码包含一位符号位,则补码真值的范围(-2n-1,2n-1 - 1), 则将其转换为…

实用指南:Eclipse 透视图(Perspective)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

? #6

100 + 0 + 80 + 0 = 180, Rank 2/6.2024暑期CSP-S&NOIP模拟赛第8套题⾯ 链接:link 题解:暂无 时间:4h (2025.10.28 14:00~18:00) 题目数:4 难度:A B C D\(\color{#F39C11} 橙\) \(\color{#FFC116} 黄\)*1000 …

鲜花:不会说明你有抑郁症3

这回是广为人知题了。自然数幂和:给定 \(n,k\),求 \(\sum_{i=1}^{n} i^k\),\(n\le 10^{18},k\le 2000\)。本来以为用扰动法求自然数幂和很猎奇,结果一搜出来十来篇博客。唉我还是太菜了。 尝试扰动法处理。 设: \…

算法竞赛知识点速通手册

1. 基础贪心:邻项交换与证明 贪心算法的精髓在于“局部最优”导向“全局最优”。然而,其正确性并非总是显而易见的,需要严谨的数学证明。邻项交换(Exchange Argument)是证明一类排序相关贪心策略最经典、最强大的…

集训做题杂记1 - -MornStar

[CTS2024] 众生之门 小清新构造题。 观察大样例可以发现答案不大于 \(3\),感性猜测可以在路径长度不超过 \(3\) 的情况下遍历整棵树,事实也确实如此。 进一步考虑答案一般为 \(0\) 和 \(1\),只有 \(n\) 比较小或者图…

CF1909I Short Permutation Problem

CF1909I Short Permutation Problem并非独立切,大量参考题解。 对于排列计数问题,考虑三个方向:容斥、连续段DP、按顺序加数。 发现容斥和连续段DP没前途,考虑按顺序加数。从 \(1\) ~ \(n\) 加数显然是不行的,因为…

ROS1 go2 vlp16 局部避障--3 篇 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

25.10.28随笔NOIP模拟赛总结

考试 开考看题,秒了 T1,感觉 T2 是简单 dp,T3 有点神秘不知道,T4 一眼有一个 \(\mathcal O(n^2)\)。于是顺序开题。T1 很快写了,T2 看了一个小时还是不会有点难崩,当时是很快想到一个 dp,设 \(f_{i,j,0/1}\) 表…

第二十八篇

今天是10月28号,上了铁道技术认知。

P8269 [USACO22OPEN] Visits S

P8269 [USACO22OPEN] Visits S 题解题目传送门 博客传送门 首先,每头牛牛都只有一个拜访对象,所以如果考虑图论建模的话,相当于每个点出度都是 1。这相当于图是个基环树森林(注意不只有一棵基环树),而且每个基环…

Luogu P13925 [POKATT 2024] 联合猫国 / The Paw-litical Game 题解 [ 蓝 ] [ 线性 DP ] [ 种类数观察 ]

联合猫国 去年模拟赛做过一道几乎一模一样的题,于是一眼秒了。 本题的一个结论:最终可合并的区间数为 \(\bm{O(n\log n)}\) 级别。 证明可以考虑构造出可合并区间数最多的序列,显然是所有数都相同时的区间数,可以取…

深入解析:【STM32项目开源】基于STM32的独居老人监护系统

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

CSP-S 41多校 9

10.28 (虽然但是下发文件NOIP?)10.28 CSP-S 前倒数第二场模拟赛,直接一道都没切出来。。。 再不放信心赛真要没信心了。 t1 dp题。 显然对于每一次行动都是一个背包dp。 变种在于背包更换,更换后容量重新计算。 所…

【25.10.28】模拟赛

T1 code #include<bits/stdc++.h> using namespace std; const int N=5e4+5,M=1e3+5; int n,m,ans=0; char s[N],t[M]; int nxt[M]; int f[N][M]; int g[M][30]; void getnxt(){nxt[1]=0;int j=0;for(int i=2;i&…

CSP-S模拟41

CSP-S模拟41 A. 数轴取物(axis) 显然可以有一个 \(O(n^3)\) 的背包 dp,设 \(dp[i][j][k]\) 表示选区间 \([i,j]\),背包容量为 \(k\) 时可获得的最大价值。每次枚举固定左端点从小到大枚举右端点,发现 \(dp[i][j]\) …

Linux双中文编码笔记

Linux双中文编码笔记/etc/locale.gen zh_CN.GB18030 GB18030zh_CN.GBK GBK 上面两行默认是被注释掉的,要打开。 /usr/sbin/dpkg-reconfigure/usr/sbin不在普通用户的PATH里,再说运行它也需要root权限。 如果dkpg-rec…

C++类和对象(1) - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …