[Tricks-00004]CF1954F(自己胡的 trick,被 Burnside 完爆)

news/2024/11/17 15:58:52/文章来源:https://www.cnblogs.com/maihe/p/18550504

介绍下自己的离奇思路:

先读清楚题意!要求是旋转等价,即两个以 \(c\)\(1\) 开头,总 \(1\) 个数不超过 \(k+c\) 的字符串算一种。

那怎么刻画"只算一种"这个条件呢?一个想法可以是,对每个字符串赋一个权值,一种字符串的权值即旋转出来的每个合法的,把它们加起来应该是 \(1\),再全部加出来。

一个直接的赋权方式是,对一个最小循环节是 \(d(d|n)\) 的字符串,它的权值为 \(\dfrac{1}{\sum\limits_{i=1}^{d}ok_i}\),其中 \(ok_i\) 代表字符串是否可以以位置 \(i\) 开头。

然后做法就是枚举 \(d\),求出容斥系数,因为要考虑所有大小为 \(d\)\(01\) 串,所以要 dp 三个量:长度,\(1\) 个数,以及合法开头点数。这样复杂度肯定没救了。

这是同学你可能会说:没必要让每个"合法点"都合法作为开头啊?我对于一个 \(len\geq c\)\(1\) 段,要求上必须以这个段的段头作为开头才可以,这不就轻松了吗?

很好!这样就改为了段数分之一,不过还是要 dp 这个段数有点烦,怎么办呢?

其实这时候你可以发现,我们没有必要非去设它的所有合法轮换的权值都相等啊!只需要加起来是 \(1\) 就可以。于是容易想到,停时定理那个设权值的方式,即 \(\dfrac{a_i}{\sum a_k}\),换在这题也就是,目前一个段到下一个合法段的距离,除掉总长,也就是 \(d\)。而目前段就是 \(1\sim c\) 开头那个尽量延伸,且要求 \(s_d=0\),即必须要是一个段头。

这下我们就不需要考虑这个字符串整体了,只需要得到一个最前的合法段,钦定即可!

其实可以两种情况分开讨论:

第一种情况的权值是 \(\dfrac{x-1}{d}\),其中 \(x\) 表示后面那个合法段的开头位置。第二种的权值就是 \(\dfrac{d}{d}=1\)

显然情况一更难,我们只考虑这个咋求。不难发现,枚举 \(x\) 的位置,和 \(x\) 前面 \(0\) 的个数,就可以通过一些预处理做到除了预处理之外单次 \(O(d^2)\) 的复杂度。

那么预处理是什么呢?也不难,就是 \(f_{i,j}\) 表示长度为 \(i\),以 \(0\) 结尾,不能出现连续 \(c\)\(1\) 的字符串数,则有转移:

\[f_{i,j}=\sum\limits_{k=0}^{c-1}f_{i-k-1,j-1} \]

其实这个甚至只用 \(+1\) 优化都可以做,完全不需要前缀和优化。不过其它一些预处理可能要前缀和优化,不过都很简单。这里是 \(O(n^2)\) 的。

最后一个小问题是我们枚举的是 \(d\),也就是钦定了有大小为 \(d\) 的循环节。注意,最小循环节一定整除其它的,所以容斥系数可以直接这么理解:

\[f_d=\dfrac{n}{d}-\sum\limits_{d|g|n\land g\neq d}f_g \]

然后乘乘加加就可以了。复杂度是 \(O(n^2+\sum\limits_{d|n}d^2)=O(\sum\limits_{i\geq 1}\dfrac{n}{i}^2)=O(n^2)\)

这是我的做法,代码如下,很短:

#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
int powdv(int x,int y=mod-2){int ans=1;while(y){if(y&1)ans=1ll*ans*x%mod;y>>=1,x=1ll*x*x%mod;}return ans;
}
int ff[3005],hh[3005];
int f[3005][3005],h[3005][3005];
int main(){int n,c,k;scanf("%d%d%d",&n,&c,&k);for(int d=n;d>=1;--d)if(n%d==0){ff[d]=powdv(d);for(int g=2*d;g<=n;g+=d)if(n%g==0){ff[d]=(ff[d]-ff[g]+mod)%mod;}}f[1][1]=1;for(int i=2;i<=n;++i)for(int j=2;j<=i;++j){f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod;if(i>c+1)f[i][j]=(f[i][j]-f[i-c-1][j-1]+mod)%mod;}h[0][0]=1;for(int i=1;i<=n;++i)for(int j=0;j<=i;++j){h[i][j]=(h[i-1][j]+(j?h[i-1][j-1]:0))%mod;}for(int i=1;i<=n;++i)for(int j=i;j>=1;--j){h[i][j-1]=(h[i][j-1]+h[i][j])%mod;}int ans=0;for(int d=c+1;d<=n;++d)if(ff[d]){int mx=(k+c)/(n/d),gs=max(0,d-mx),he=0;for(int i=1;i<=d-c;++i)for(int j=gs;j<=i;++j){he=(he+1ll*d*f[i][j])%mod;}for(int i=1;i<=d;++i)hh[i]=0;for(int i=c+2;i<=d-c;++i){int ht=0;for(int j=1;j<=i;++j){hh[j]=(hh[j]+f[i-c-1][j])%mod;ht=(ht+1ll*hh[j]*h[d-c-i][max(0,gs-1-j)])%mod;}he=(he+1ll*(i-1)*ht)%mod;}ans=(ans+1ll*ff[d]*he)%mod;}if(k==n-c)ans=(ans+1)%mod;printf("%d\n",ans);return 0;
}

另外说说 Burnside 的做法,也是积累了一个套路:

------------------分割线--------------------

看了眼题解,怎么这么简单???我最开始的时候想用 Burnside,可是发现不完备,遂放弃。实际你仔细想想,发现我只要不要求必须以 \(c\)\(1\) 开头就好了啊!!!!!只用这样一件事情:存在相邻 \(c\) 个字符全为 \(1\),之后就还是枚举循环节去 Burnside 就好了。思维难度少了 \(114514\) 倍,唉唉唉。

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

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

相关文章

工控机维修数据恢复

工控机是一种加固的增强型个人计算机,由于经常在环境比较恶劣的情况下运行,对数据的安全性要求也更高。 一、数据丢失的原因 用户误操作:如错误删除文件、不小心切断电源等,这些操作可能导致数据丢失或损坏。 入侵与感染:恶意程序可能破坏硬盘数据,甚至具有格式硬盘的功能…

RAG 系统高效检索提升秘籍:如何精准选择 BGE 智源、GTE 阿里与 Jina 等的嵌入与精排模型的完美搭配

RAG 系统高效检索提升秘籍:如何精准选择 BGE 智源、GTE 阿里与 Jina 等的嵌入与精排模型的完美搭配RAG 系统高效检索提升秘籍:如何精准选择 BGE 智源、GTE 阿里与 Jina 等的嵌入与精排模型的完美搭配 Text Embedding 榜单:MTEB、C-MTEB 《MTEB: Massive Text Embedding Benc…

Golang的GMP调度模型与源码解析

0、引言 我们知道,这当代操作系统中,多线程和多进程模型被广泛的使用以提高系统的并发效率。随着互联网不断的发展,面对如今的高并发场景,为每个任务都创建一个线程是不现实的,使用线程则需要系统不断的在用户态和内核态之间不断的切换,引起不必要的损耗,于是引入了协程…

有限状态机(FSM)的使用

有限状态机的使用 有限状态机在游戏制作中十分常见,它既可以作为玩家角色的控制框架,纯代码控制动画的播放,免去动画间的“连连看”;也可以制作简单的AI,甚至还可以搭配其它AI决策方式做出更复杂易用的AI控制……本文仅是个人对有限状态机的理解,与大家一同交流有限状态机…

【学习篇】patran设置阻尼

在数学和力学甚至机械专业中,质量-弹簧-阻尼系统是基础、经典的模型。其数学模型表示为: $$ m\ddot{x} +c\dot{x} +kx = 0 \qquad(1) $$ 有限元模型比较简单,就是两个质量点+弹簧假设上述式子的初值为 $$ \begin{cases} u(0)=0.2 \ \dot{u}(0)=0 \end{cases} $$ 各项系数为变…

mysql 查询每个订单总价和购买商品的总类数

数据表 CREATE TABLE goods ( order_id INT NOT NULL, goods_id INT NOT NULL, price DECIMAL(10, 2) NOT NULL ); 插入数据 INSERT INTO goods (order_id, goods_id, price) VALUES (1, 1, 3.5), (1, 2, 4.0), (2, 4, 6.0); 数据查询 SELECT order_id, SUM(price) AS total_pr…

【视频讲解】Python深度神经网络DNNs-K-Means(K-均值)聚类方法在MNIST等数据可视化对比分析

全文链接:https://tecdat.cn/?p=38289 原文出处:拓端数据部落公众号 分析师:Cucu Sun 近年来,由于诸如自动编码器等深度神经网络(DNN)的高表示能力,深度聚类方法发展迅速。其核心思想是表示学习和聚类可以相互促进:好的表示会带来好的聚类效果,而好的聚类为表示学习提…

时间

JDK7 时间 全世界的时间, 有一个统一的计算标准. 格林尼治时间/格林威治时间 (Greenwich Mean Time) 简称 GMT. 计算核心: 地球自转一天是 24 小时, 太阳直射时为正午 12 点. 后来发现计算误差较大, 现在格林威治时间已经不再作为标准时间来使用了. 到了 2012 年 1 月, 取消了用…

贴代码框架PasteForm特性介绍之markdown和richtext

简介 PasteForm是贴代码推出的 “新一代CRUD” ,基于ABPvNext,目的是通过对Dto的特性的标注,从而实现管理端的统一UI,借助于配套的PasteBuilder代码生成器,你可以快速的为自己的项目构建后台管理端!目前管理端只有Html+js版本的,后续将支持小程序,Vue等 案例源码 案例源…

MATLAB用CNN-LSTM神经网络的语音情感分类深度学习研究

全文链接:https://tecdat.cn/?p=38258 原文出处:拓端数据部落公众号 在语音处理领域,对语音情感的分类是一个重要的研究方向。本文将介绍如何通过结合二维卷积神经网络(2 - D CNN)和长短期记忆网络(LSTM)构建一个用于语音分类任务的网络,特别是针对语音情感识别这一应…

2024长城靶场训练

仿射密码 首先题目描述 使用仿射函数y=3x+9加密得到的密文为JYYHWVPIDCOZ,请尝试对其解密。flag为flag{大写明文}。 1、使用在线网站直接破解或手工计算破解,获得flag。(参数a=3,b=9,对应仿射函数y=3x+9) 仿射密码加密_仿射密码解密手工计算使用解密函数为D(x) = a^-1(x …