数组成鸡

数组成鸡

题目描述

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

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

输入描述:

第一行输入两个正整数 nQ (2n105, 1Q5×105),表示数组长度与询问次数。

第二行输入 n 个空格分隔的整数 ai (109ai109),表示数组中的元素。

接下来 Q 个空格分隔的整数 M (109M109),表示询问的数字。

输出描述:

对于每个 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| 最大为 109<230,所以如果操作后 a 中绝对值大于 1 的元素数量至少为 30 时,|ai|230>|M|。为此如果 n30,我们只能将某些数变成 11,然后再判断所有数乘积的绝对值是否不超过 109,如果不超过则把乘积结果存到 std::set 中。如果 n<30,则需要保证操作后最小的两个元素的绝对值不能同时大于 109,因此只需暴力枚举操作次数 109109,如果所有数乘积的绝对值不超过 109则存到 std::set 中。最后询问只需判断 M 是否在集合中即可。下面给出具体做法。

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

  如果 n30,对 a 排序,分别枚举 a0[109,109]a1[109,109] 的情况,即分别加 a0+i1 和加 a1+i1i[109,109]。计算量大概是 30×109 级别。

  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/

posted @   onlyblues  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2023-02-15 Nim游戏
Web Analytics
点击右上角即可分享
微信分享提示