首页 > 其他分享 >数组成鸡

数组成鸡

时间:2024-02-15 20:45:26浏览次数:24  
标签:10 No int 30 sqrt leq 组成

数组成鸡

题目描述

小鸡有一个由整数组成的数组,小鸡可以对这个数组进行任意次(可以不进行)全数组每个数加一或全数组每个数减一的操作。

现在,小鸡想让你回答 $Q$ 次询问,每次询问给出一个整数 $M$,你需要回答任意次(可以不操作)操作后是否可以使得给定数组的乘积等于给出的整数 $M$。

输入描述:

第一行输入两个正整数 $n$,$Q$ ($2 \leq n \leq10^5$, $1 \leq Q \leq 5 \times 10^5$),表示数组长度与询问次数。

第二行输入 $n$ 个空格分隔的整数 $a_i$ ($-10^9 \leq a_i \leq 10^9$),表示数组中的元素。

接下来 $Q$ 个空格分隔的整数 $M$ ($−10^9 \leq M \leq 10^9$),表示询问的数字。

输出描述:

对于每个 $M$,请你输出一行 "Yes" 或 "No"(不含引号)表示是否可以令全数组的乘积等于给定 $M$。

示例1

输入

4 9
1 -1 3 5
-75 19305 123 1 0 15 -15 1919810 114514

输出

No
Yes
No
No
Yes
No
Yes
No
No

 

解题思路

  由于询问的 $|M|$ 最大为 $10^9 < 2^{30}$,所以如果操作后 $a$ 中绝对值大于 $1$ 的元素数量至少为 $30$ 时,$\left| \prod{a_i} \right| \geq 2^{30} > |M|$。为此如果 $n \geq 30$,我们只能将某些数变成 $1$ 或 $-1$,然后再判断所有数乘积的绝对值是否不超过 $10^9$,如果不超过则把乘积结果存到 std::set 中。如果 $n < 30$,则需要保证操作后最小的两个元素的绝对值不能同时大于 $\sqrt{10^9}$,因此只需暴力枚举操作次数 $-\sqrt{10^9} \sim \sqrt{10^9}$,如果所有数乘积的绝对值不超过 $10^9$则存到 std::set 中。最后询问只需判断 $M$ 是否在集合中即可。下面给出具体做法。

  如果 $n \geq 30$,用 $c_x$ 来表示初始 $a$ 中元素 $x$ 数量,枚举每一种数 $a_i$(即重复的只枚举 $1$ 次),先通过加 $-a_i + 1$ 次 $1$ 把 $a_i$ 变成 $1$(元素 $a_i - 2$ 会变成 $-1$)。如果 $n - c_{a_i} - c_{a_i-2} < 30$,则检查操作后 $a$ 的乘积的绝对值是否不超过 $10^9$。同理把 $a_i$ 变成 $-1$。其中检查的部分是暴力枚举,时间复杂度为 $O(n)$,但实际上检查的次数非常少(最多应该只有一次),因为如果要满足 $n - c_x - c_{x-2} < 30$,意味着 $c_x + c_{x-2} > n - 30$,此时整个 $a$ 中基本都是元素 $x$ 或 $x-2$。

  如果 $n \geq 30$,对 $a$ 排序,分别枚举 $a_0 \in [-\sqrt{10^9}, \sqrt{10^9}]$ 和 $a_1 \in [-\sqrt{10^9}, \sqrt{10^9}]$ 的情况,即分别加 $-a_0 + i$ 次 $1$ 和加 $-a_1 + i$ 次 $1$,$i \in [-\sqrt{10^9}, \sqrt{10^9}]$。计算量大概是 $30 \times \sqrt{10^9}$ 级别。

  AC 代码如下:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 2e5 + 10;

int n, m;
int a[N];
set<int> st({0});

void get(int x) {
    LL t = 1;
    for (int i = 0; i < n; i++) {
        t *= (a[i] + x);
        if (abs(t) > LL(1e9)) return;
    }
    st.insert(t);
}

int main() {
    scanf("%d %d", &n, &m);
    map<int, int> mp;
    for (int i = 0; i < n; i++) {
        scanf("%d", a + i);
        mp[a[i]]++;
    }
    sort(a, a + n);
    if (n >= 30) {
        for (int i = 0; i < n; i++) {
            if (!i || a[i] != a[i - 1]) {
                if (n - mp[a[i]] - mp[a[i] - 2] < 30) get(-a[i] + 1);
                if (n - mp[a[i]] - mp[a[i] + 2] < 30) get(-a[i] - 1);
            }
        }
    }
    else {
        for (int i = -31622; i <= 31622; i++) {
            get(-a[0] + i);
            get(-a[1] + i);
        }
    }
    while (m--) {
        int x;
        scanf("%d", &x);
        printf("%s\n", st.count(x) ? "Yes" : "No");
    }
    
    return 0;
}

 

参考资料

  【出题人讲题】2024牛客寒假算法基础集训营1 题解:https://www.bilibili.com/video/BV1Ry421a7pW/

  2024牛客寒假算法基础集训营1(全部题目详解):https://www.bilibili.com/video/BV1Ty421a7vN/

标签:10,No,int,30,sqrt,leq,组成
From: https://www.cnblogs.com/onlyblues/p/18016563

相关文章

  • nginx+keepalived组成高可用集群
    注意:用keepalived将多台nginx组成高可用集群时,nginx不能用docker启动1下载keepalived:yum-yinstallkeepalived2查看网卡:ipaddr,有eth0,en33这种的就是网卡名,inet后面是ip地址,一个网卡还可以绑定多个ip地址,比如给eth0网卡添加192.168.0.150ip命令:ipaddradd192.168......
  • 《深入浅出计算机组成原理》学习笔记1——计算机基本组成与指令执行
    一丶冯·诺依曼体系结构:计算机组成的金字塔1.从装机的角度看计算机基本组成CPU:计算机最重要的核心配件,全称中央处理器,计算机的所有“计算”都是由CPU来进行的内存撰写的程序、打开的浏览器、运行的游戏,都要加载到内存里才能运行。程序读取的数据、计算得到的结果,也都要......
  • 计算机组成原理(期末版)
    1.三个周期指令周期:一条机器指令执行所需的时间(由若干个机器周期来表示)机器周期:完成一个规定操作所用的时间(如读写一次存储器等操作所需要的时间)时钟周期:(又称节拍脉冲)时钟周期是计算机系统中用来衡量处理器执行指令或完成一个操作所需时间的概念。它表示在处理器内部的时钟信......
  • 一文读懂工业交换机的组成结构
    工业交换机的具体组成结构主要包括以下几个部分:1.芯片交换器:芯片交换器是工业交换机最重要的组件,其职责是进行数据包的转发和处理,并支持各种网络协议和数据通信方式。2.端口是实现工业交换机与外部设备进行数据交换的连接接口。端口通常有多种类型,例如RJ45口和光口等,可以满足各种设......
  • 根据输入,输出由“*”组成的x图案
    题目:输入3,输出3行3列的x图形,图形由“*”组成。根据分析,可以把x视为一个拥有"*"和"空格"的一个矩形。当行与列的下标相同,或相加为n时,输出*,其余输出空格#include<stdio.h>intmain(){ intn=0; inti=0; intj=0; scanf("%d",&n); printf("\n"); for(i=0;i......
  • Spring基础 - Spring和Spring框架组成
    什么是Spring?Spring的起源要谈Spring的历史,就要先谈J2EE。J2EE应用程序的广泛实现是在1999年和2000年开始的,它的出现带来了诸如事务管理之类的核心中间层概念的标准化,但是在实践中并没有获得绝对的成功,因为开发效率,开发难度和实际的性能都令人失望。曾经使用过EJB开发JAVAEE......
  • 模型组成的编程世界
    现实世界中的树,它被人起名叫做树,就是人给这种特征的集合做了一个模型,并给其命名为树。编程的世界中也有很多的专有名词,这就是程序员先辈们给模型命的名。吸收二氧化碳,阳光催化,生根于土地————>树各种特征的集合————>模型模型的存在一定程度上减少了记忆的复杂程度......
  • 路由器系列--【如何使用路由器组成一个局域网?】
    1.原理如图2.设置常用参数常用DNS:114.114.114.114、8.8.8.8常用子网掩码:255.255.255.0ip地址:和路由器网关地址保持在同一网段即可这样设置完之后,如果路由器能联网,几台电脑也能正常联网。如果路由器不能联网,几台电脑之间可以相互访问,也就是组成了一个大局域网。如果有一台......
  • 计算机组成原理 复习笔记
    蒽,谁说不是速成指南呢。目录11Intro12-13指令系统计算机程序与指令系统语言高级语言/算法语言汇编语言机器语言冯诺依曼结构计算机指令和指令系统RISC-V指令系统架构特点特权模式14数据表示及检错纠错数据表示逻辑型数据表示字符的表示数值数据:整数、浮点数数值范围和数......
  • 写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中
    描述写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母)数据范围:1\len\le1000\1≤n≤1000输入描述:第一行输入一个由字母、数字和空格组成的字符串,第二行输入一个字符(保证该字符不为空格)。输出描述:......