Codeforces Round 924 E. Modular Sequence

E. Modular Sequence

E

题意

对于一个长度为 n n n 的数组 a a a,定义它是 g o o d good good 的当且仅当:

  • a 1 = x a_1 = x a1=x
  • a i = a i − 1 + y a_{i} = a_{i - 1} + y ai=ai1+y a i = a i − 1 m o d y i ≥ 2 a_{i} = a_{i - 1} mod \hspace{3pt} y \quad i \geq 2 ai=ai1modyi2

给定 n 、 x 、 y 、 S n、x、y、S nxyS,问能否构造出一个 S S S 的长度为 n n n g o o d good good 数组

思路

注意到后面每个放置的 a i a_i ai,它们模除 y y y 的值都是一样的,因为自从 a 1 = x a_1 = x a1=x 后,后面每次变化都是同余 y y y 的。

定义 r = x m o d y r = x \hspace{3pt} mod \hspace{3pt} y r=xmody,那么我们先将数组的 n n n 个位置填成: a i = r a_i = r ai=r a 1 = x a_1 = x a1=x,先计算一下这样子最小的数组和是否超过 S S S,超过的话显然没有答案。对于没有超过 S S S 的时候,我们后面肯定是要在 r r r 的基础上放置若干个 y y y,那么剩余要放置的和应该能被 y y y 整除 才行。

假设要放置 l e f t S u m y leftSum \over y yleftSum y y y,我们就一定要尽可能用最短的长度构造出来这么多个 y y y 的放置方式,考虑 D P DP DP,用 d p k dp_k dpk 表示要从空序列开始放置 k k k 个物品,最短需要的长度,那么转移我们可以枚举最后使用的完整上升长度 l e n len len,这个上升长度必须从 0 0 0 开始,长度为 l e n len len,例如: . . . . , 0 , 1 , 2 , . . . , l e n − 1 ...., 0, 1, 2, ..., len - 1 ....,0,1,2,...,len1 这样一个结尾方式,那么它的子状态就是: d p [ k − l e n ⋅ ( l e n − 1 ) 2 ] dp[k - \frac{len \cdot (len - 1)}{2}] dp[k2len(len1)],因为最后这一段上升序列的贡献是 l e n ⋅ ( l e n − 1 ) 2 \frac{len \cdot (len - 1)}{2} 2len(len1),长度为 l e n len len,我们取 m i n min min 值就可以

对于多组样例,我们只需要关心最后要放置多少个 y y y,所以我们可以预计算 d p dp dp 数组

我们先枚举一开始是否需要先跟着 x x x 递增一段长度,然后再从 0 0 0 开始构造答案,因为我们的 d p dp dp 数组是从 0 0 0 开始构造答案的最短长度,假设一开始从 x x x 开始递增了 k k k 次(不包含 a 1 a_1 a1 ),也就是数组开头为: x , x + y , x + 2 y , . . . , x + k y x, x + y, x + 2y, ..., x + ky x,x+y,x+2y,...,x+ky,这样子的形式,我们得先确保这个 p r e S u m preSum preSum 不会超过 S S S,然后在此基础上计算后面还需要放置的和的余量 l e f t S u m = S − p r e S u m leftSum = S - preSum leftSum=SpreSum,当然这个余量要先预算一下后面每个位置放一个 r r r 的花销, l e f t S u m − = r × ( n − 1 − k ) leftSum -= r \times (n - 1 - k) leftSum=r×(n1k),最后的这个 l e f t S u m leftSum leftSum 不能为负数,并且要能被 y y y 整除,还要要求 d p [ l e f t S u m y ] dp[{leftSum \over y}] dp[yleftSum] 的值小于等于 n − 1 − k n - 1 - k n1k,意思是我们剩余的位置必须要足够放置这么多个 y y y,我们才能在这个基础上构造答案

如果上述条件都符合,我们现在中间多余的用不上的位置 [ k + 1 , n − d p [ l e f t S u m y ] ] [k + 1, n - dp[{leftSum \over y}]] [k+1,ndp[yleftSum]] 先填补上 r r r,然后从 n − d p [ l e f t S u m y ] + 1 n - dp[{leftSum \over y}] + 1 ndp[yleftSum]+1 这个位置开始构造答案,我们用一个 l e n len len 数组来暂存一下我们的答案构造的上升长度序列,枚举转移的路径即可

时间复杂度: O ( S S ) O(S \sqrt{S}) O(SS )

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n'
#define ull unsigned long long
#define ALL(v) v.begin(), v.end()
#define Debug(x, ed) std::cerr << #x << " = " << x << ed;

const int INF=0x3f3f3f3f;
const long long INFLL=1e18;

typedef long long ll;

const int N = 200050;

int dp[N];

void solve(){
    int n;
    ll x, y, S;
    std::cin >> n >> x >> y >> S;
    fore(k, 0, n){ //除了首项x外,后面还跟着递增了k次
        ll preSum = (k + 1) * x + k * (k + 1) / 2 * y; //前缀和
        if(preSum > S) continue;
        ll leftSum = S - preSum; //后面需要构造的和
        leftSum -= (n - 1 - k) * (x % y); //先减去模数 x % y
        if(leftSum < 0 || leftSum % y) continue;
        
        int needSum = leftSum / y; //后面需要多少个y
        if(dp[needSum] > n - k - 1) continue; //长度不够构造
        
        std::vector<int> a(n);
        a[0] = x; //首项
        fore(i, 1, k + 1) a[i] = a[i - 1] + y; //起初跟着长度为k的一个递增
        fore(i, k + 1, n - dp[needSum]) a[i] = x % y; //中间这里用不上,我们在 n - dp[needSum] -> n - 1构造

        int idx = n - dp[needSum];

        std::vector<int> len;
        while(needSum){
            for(int l = 2; l * (l - 1) / 2 <= needSum; ++l)
                if(dp[needSum] == dp[needSum - l * (l - 1) / 2] + l){ //这是一个最短长度的转移
                    len.push_back(l); //记录构成最短长度的转移
                    needSum -= l * (l - 1) / 2; //剩余需要放置的y的数量
                    break;
                }
        }

        for(auto l : len) //按照答案转移放置y
            fore(j, 0, l) //从0开始放置,放 l 次
                a[idx++] = x % y + j * y; //记住底是 x % y
        
        std::cout << "YES\n";

        for(auto el : a) std::cout << el << ' ';
        std::cout << endl;
        return;
    }

    std::cout << "NO\n";
}

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    fore(i, 1, N) dp[i] = INF;
    fore(k, 1, N)   //dp[i] 表示要放 i 个 y 需要的最短长度是多长
        for(int len = 2; len * (len - 1) / 2 <= k; ++len) //这里len是从0开始放的,所以最后一位是len - 1,长度为len
            dp[k] = std::min(dp[k], dp[k - len * (len - 1) / 2] + len);

    int t;
    std::cin >> t;
    while(t--){
        solve();
    }
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

kali最新最简单安装

之前都是用iso镜像文件的 今年好多东西都删库了&#xff0c;所有还是要主要资源的保存 去官网找下载 一般来说都是用虚拟机的 下载完会是一个压缩文件&#xff0c; 解压&#xff0c;然后操作之前需要先下载虚拟机 打开方式用虚拟机打开 kali就按装好了

【Java EE初阶十二】网络编程TCP/IP协议(一)

1. 网络编程 通过网络&#xff0c;让两个主机之间能够进行通信->就这样的通信来完成一定的功能&#xff0c;进行网络编程的时候&#xff0c;需要操作系统给咱们提供一组API&#xff0c;通过这些API来完成编程&#xff1b;API可以认为是应用层和传输层之间交互的路径&#xf…

STM32 cubemx配置DMA+空闲中断接收不定长数据

文章目录 前言一、串口空闲中断二、DMA空闲中断接收不定长数据实现思路三、STM32Cubemx配置DMA空闲中断接收不定长数据四、代码编写总结 前言 本篇文章给大家讲解一下DMA串口空闲中断接收串口不定长数据&#xff0c;之前我们也是讲解过串口接收不定长数据的&#xff0c;那么本…

详细分析Redis中数值乱码的根本原因以及解决方式

目录 前言1. 问题所示2. 原理分析3. 拓展 前言 对于这方面的相关知识推荐阅读&#xff1a; Redis框架从入门到学精&#xff08;全&#xff09;Java关于RedisTemplate的使用分析 附代码java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09; …

力扣 第 383 场周赛 解题报告 | KMP

力扣 第 383 场周赛 解题报告 | KMP 链接 前言 一个人能走的多远不在于他在顺境时能走的多快&#xff0c;而在于他在逆境时多久能找到曾经的自己。 T1 修改矩阵 思路&#xff1a;模拟 时间复杂度&#xff1a; O ( m n ) O(mn) O(mn) class Solution:def modifiedMatrix(se…

读书笔记之《重塑大脑重塑人生》:大脑强大的可塑性

《重塑大脑重塑人生》作者是诺曼道伊奇&#xff0c;原作名: The Brain That Changes Itself: Stories of Personal Triumph from the Frontiers of Brain Science &#xff0c;于 2015-1-20出版。 诺曼•道伊奇&#xff08;Norman Doidge&#xff09;是医学博士&#xff0c;精…

leetcode题目记录

文章目录 单调栈[127. 单词接龙](https://leetcode.cn/problems/word-ladder/)[139. 单词拆分](https://leetcode.cn/problems/word-break/)[15. 三数之和](https://leetcode.cn/problems/3sum/)[140. 单词拆分 II](https://leetcode.cn/problems/word-break-ii/)[113. 路径总和…

C++ STL string类使用及实现详解

1. string简介 C语言中&#xff0c;可以用字符数组来存储字符串&#xff0c;如&#xff1a; char ch[] "hello world"; C中&#xff0c;可以使用string类对象来存储字符串&#xff0c;使用起来比C语言中的字符数组要方便得多&#xff0c;而且不用考虑容量的问题。…

C#,普洛尼克数(Pronic Number)的算法与源代码

1 普洛尼克数(pronic number) 普洛尼克数(pronic number)&#xff0c;也叫矩形数、欧波朗数(oblong number)&#xff0c;是两个连续非负整数的积&#xff0c;即mn*(n1)。第n个普洛尼克数侪是n个三角形数个两倍。 2 计算结果 3 源程序 using System; namespace Legalsoft.Tru…

c++之说_14|左值引用与右值引用

提起左右值引用我就头疼 左值&#xff1a; 1、在内存中开辟了空间的便叫左值 2、左值不一定可以赋值 如字符串常量 3、左值可以取地址 右值&#xff1a; 1、在内存中没有开辟空间的 2、右值无法取地址 如&#xff1a; 立即数&#xff08;1&#xff0c;2&#xff0c;3…

Unity类银河恶魔城学习记录7-1 P67 Sword Throw Skill State源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Sword_Skill.cs using System.Collections; using System.Collections.Gen…

nba2k24 韩旭面补

nba2k23-24 韩旭面补 nba2k23-nba2k24通用 韩旭面补 下载地址&#xff1a; https://www.changyouzuhao.cn/9605.html

【原创 附源码】Flutter安卓及iOS海外登录--Tiktok登录最详细流程

最近接触了几个海外登录的平台&#xff0c;踩了很多坑&#xff0c;也总结了很多东西&#xff0c;决定记录下来给路过的兄弟坐个参考&#xff0c;也留着以后留着回顾。更新时间为2024年2月7日&#xff0c;后续集成方式可能会有变动&#xff0c;所以目前的集成流程仅供参考&#…

Flex布局 (上万字)超详细讲解 这篇就够了

一、Flex概述 Flex布局&#xff0c;全称为“Flexible Box Layout”&#xff0c;意为“弹性盒布局”。它是一种现代的CSS布局模式&#xff0c;旨在提供一种更有效的方式来布局、对齐和分配容器中项目之间的空间&#xff0c;即使它们的大小未知或动态变化。 Flex布局的主要特点…

Unity类银河恶魔城学习记录6-2 P66 Clone‘s Attack源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Clone_Skill.cs using System.Collections; using System.Collections.Gen…

二叉搜索树删除操作的递归与非递归写法

如何进行删除操作 对于二叉搜索树的删除操作&#xff0c;主要分为以下3种情况讨论&#xff1a; 1、删除的结点没有左右孩子 2、删除的结点只有一个孩子 3、删除的结点有左右孩子 所以&#xff0c;我们将会用if…else…分为最多3种情况讨论&#xff08;实际上只分了两种&#x…

关于java的多线程初识

关于java的多线程初识 我们从今天开始&#xff0c;正式学习java的多线程&#xff0c;我们在前面的文章中学习到了java的基础&#xff0c; 但是距离我们工作实战还差的很远&#xff0c;我们学习好了基础&#xff0c;以后的文章会逐步的深入&#xff0c;去讲解各种前端框架&…

同余数论性质

同余概念 当 a%m b%m&#xff0c;说明a和b同余&#xff0c;写作若 a≡b(mod m) 性质 衍生出几条性质 1.m | abs(a-b)&#xff0c;即|a-b|是m的倍数。&#xff08;注意&#xff0c;0是任何数的倍数&#xff09; 2.当a≡b(mod m)&#xff0c;c≡d(mod m)&#xff0c; 有ac…

IDEA Ultimate下载(采用JetBrain学生认证)

IDEA Ultimate版本下载 Ulitmate是无限制版&#xff08;解锁所有插件&#xff0c;正版需要付费。学生可以免费申请许可&#xff09;Community是开源社区版本&#xff08;部分插件不提供使用&#xff0c;比如Tomcat插件。免费&#xff09; 我们将通过学生认证获取免费版。 Je…

【vue3学习笔记】shallowReactive与shallowRef;readOnly与shallowReadOnly;toRaw与markRaw

尚硅谷Vue2.0Vue3.0全套教程丨vuejs从入门到精通 课程 P158节 《shallowReactive与shallowRef》笔记&#xff1a; reactive()与shallowReactive()&#xff1a;reactive()处理后的数据是响应式的&#xff0c;对象内嵌套的深层结构全部是响应式的。shallowReactive()处理后的数据…