Codeforces Round 924 E. Modular Sequence

news2024/11/22 22:51:00

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;
}

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

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

相关文章

【Linux】内核中的链表

&#x1f525;博客主页&#xff1a;PannLZ &#x1f38b;系列专栏&#xff1a;《Linux系统之路》 &#x1f94a;不要让自己再留有遗憾&#xff0c;加油吧&#xff01; 文章目录 链表1.创建和初始化2.创建节点3.添加节点4.删除节点5.遍历 链表 内核开发者只实现了循环双链表&am…

nodejs学习计划--(十)会话控制及https补充

一、会话控制 1.介绍 所谓会话控制就是 对会话进行控制 HTTP 是一种无状态的协议&#xff0c;它没有办法区分多次的请求是否来自于同一个客户端&#xff0c; 无法区分用户 而产品中又大量存在的这样的需求&#xff0c;所以我们需要通过 会话控制 来解决该问题 常见的会话控制…

中科大计网学习记录笔记(十):P2P 应用

前言&#xff1a; 学习视频&#xff1a;中科大郑烇、杨坚全套《计算机网络&#xff08;自顶向下方法 第7版&#xff0c;James F.Kurose&#xff0c;Keith W.Ross&#xff09;》课程 该视频是B站非常著名的计网学习视频&#xff0c;但相信很多朋友和我一样在听完前面的部分发现信…

CSP-动态规划-最长公共子序列(LCS)

一、动态规划 动态规划&#xff08;Dynamic Programming&#xff0c;简称DP&#xff09;主要用于求解可以被分解为相似子问题的复杂问题&#xff0c;特别是在优化问题上表现出色&#xff0c;如最短路径、最大子数组和、编辑距离等。动态规划的核心思想是将原问题分解为较小的子…

【MySQL】MySQL函数学习和总结

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-Ny0xnYjfHqF7s3aS {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

C++ //练习 6.3 编写你自己的fact函数,上机检查是否正确。

C Primer&#xff08;第5版&#xff09; 练习 6.3 练习 6.3 编写你自己的fact函数&#xff0c;上机检查是否正确。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /********************************************************…

Linux系统中HTTP代理的常见问题及解决方案

亲爱的Linux用户们&#xff0c;是不是有时候觉得HTTP代理就像是一个魔法盒子&#xff0c;让你在数字世界中自由穿梭&#xff1f;但是&#xff0c;就像所有的魔法物品一样&#xff0c;它也会偶尔出点小状况。今天&#xff0c;我们就来一起探讨一下Linux系统中HTTP代理的常见问题…

购物|电商购物小程序|基于微信小程序的购物系统设计与实现(源码+数据库+文档)

电商购物小程序目录 目录 基于微信小程序的购物系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户前台功能实现 2、管理员后台功能实现 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码 六、论文参考 七、最新计算机毕设…

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

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

【数据结构】14 队列(带头结点的链式存储和顺序存储实现)

定义 队列是一个有序线性表&#xff0c;但是队列的插入、删除操作是分别在线性表的两个不同端点进行的。 设一个队列 Q ( a 1 , a 2 , . . . , a n ) Q (a_1, a_2,...,a_n) Q(a1​,a2​,...,an​)&#xff0c;那么 a 1 a_1 a1​被称为队头元素&#xff0c; a n a_n an​为队…

漫漫数学之旅017

文章目录 经典格言数学习题古今评注名人小传&#xff08;一&#xff09;亚当斯密&#xff08;二&#xff09;J理查德高特三世 经典格言 科学是热情与迷信之毒的最佳解毒剂。——亚当斯密&#xff08;Adam Smith&#xff09; 咳咳&#xff0c;各位看官&#xff0c;且听我用轻松…

leetcode:买卖股票最佳时机二

思路&#xff1a; 使用贪心算法&#xff1a;局部最优是将买卖过程中产生的正数进行相加&#xff0c;进而使得最后结果最大&#xff08;全局最优&#xff09;。 price [7,1,5,10,3,6,4] -6,4,5,-7,3,-2 正数相加就得到了最大 代码实现&#xff1a; 1.循环中下标从1开始 …

文件包含知识点详细总结

如果想看图片和观感更好的话,可以直接去我的github或者gitbook github:https://github.com/kakaandhanhan/cybersecurity_knowledge_book-gitbook.22kaka.fun gitbook:http://22kaka.fun description: 这里将通过参考文章和做题一起进行总结,并且文件包含漏洞,很多都利用了…

CVE-2022-25487 漏洞复现

漏洞描述&#xff1a;Atom CMS 2.0版本存在远程代码执行漏洞&#xff0c;该漏洞源于/admin/uploads.php 未能正确过滤构造代码段的特殊元素。攻击者可利用该漏洞导致任意代码执行。 其实这就是一个文件上传漏洞罢了。。。。 打开之后&#xff0c;/home路由是个空白 信息搜集&…

常见的单片机及其功能

在当今电子技术快速发展的时代&#xff0c;单片机作为核心组件&#xff0c;在各类电子项目和产品中扮演着至关重要的角色。它们的应用范围从简单的家用电器控制到复杂的工业自动化系统&#xff0c;几乎无处不在。接下来&#xff0c;我们将以轻松的语言&#xff0c;探讨几种广泛…

InternLM大模型实战-3.InternLM+Langchain搭建知识库

文章目录 前言笔记正文大模型开发范式RAGFinetune LangChain简介构建向量数据库搭建知识库助手1 InternLMLangchain2 构建检索问答链3 优化建议 Web Demo 部署搭建知识库 前言 本文是对于InternLM全链路开源体系系列课程的学习笔记。【基于 InternLM 和 LangChain 搭建你的知识…

RS232、RS485 和 DB9 接口详解

简介&#xff1a; 本文介绍了 RS232 和 RS485 两种串行通信协议的物理层标准&#xff0c;以及它们与 DB9 接口的连接方式。此外&#xff0c;还介绍了 RS485 接口的全双工和半双工模式&#xff0c;以及它们的应用场景。 1. DB9 接口 DB9 接口是一种常见的 D 型连接器&#xff…

C#在窗体正中输出文字以及输出文字的画刷使用

为了在窗体正中输出文字&#xff0c;需要获得输出文字区域的宽和高&#xff0c;这使用MeasureString方法&#xff0c;方法返回值为Size类型&#xff1b; 然后计算输出的起点的x和y坐标&#xff0c;就可以输出了&#xff1b; using System; using System.Collections.Generic; …

springboot180基于spring boot的医院挂号就诊系统

医院挂号就诊系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装医院挂号就诊系统软件来发挥其…

限制资源使用

限制资源使用 您需要显示对服务器资源的访问来保护Web应用程序和应用程序数据不受未授权用户的访问。在Java EE Web应用程序中,您可以通过在应用服务器中创建用户和用户组来保护资源免受未经授权的访问。您可以为应用程序定义角色并在部署过程中将角色分配给用户。 1. 创建授权…