Codeforces Round #689 (Div. 2, based on Zed Code Competition) D. Divide and Summarize

翻译:Mike收到了一个长度为𝑛的数组𝑎作为生日礼物,他决定测试一下这个数组到底有多漂亮。

如果有一种方法可以使用一定数量(可能为零)的切片操作获得一个元素总和为𝑠𝑖的数组,则数组将通过𝑖-th漂亮性测试。


数组切片操作的实现方式如下:

假设𝑚𝑖𝑑=⌊𝑚𝑎𝑥(𝑎𝑟𝑟𝑎𝑦)+𝑚𝑖𝑛(𝑎𝑟𝑟𝑎𝑦)/2⌋,哪里𝑚𝑎𝑥和𝑚𝑖𝑛——函数查找数组元素最大值和最小值。换句话说,𝑚𝑖𝑑是𝑎𝑟𝑟𝑎𝑦的最大元素和最小元素的和,再除以2的舍入。
然后将数组分为左和𝑟𝑖𝑔ℎ𝑡两部分。左边数组包含所有小于或等于𝑚𝑖𝑑的元素,而𝑟𝑖𝑔ℎ𝑡数组包含所有大于𝑚𝑖𝑑的元素。左边和𝑟𝑖𝑔ℎ𝑡中的元素与𝑎𝑟𝑟𝑎𝑦保持相对顺序。
在第三步中,我们选择希望保留左边数组和𝑟𝑖𝑔ℎ𝑡数组中的哪一个。所选的数组将替换当前的数组,而另一个数组将被永久丢弃。
你需要帮助迈克找出𝑞漂亮测试的结果。

请注意,您测试的是数组𝑎的美观性,因此您使用原始(初始)数组𝑎开始每个美观性测试。因此,第一个切片(如果需要)总是在数组𝑎上执行。

输入
每个测试包含一个或多个测试用例。第一行包含测试用例的数量𝑡(1≤𝑡≤100)。

每个测试用例的第一行包含两个整数𝑛和𝑞(1≤𝑛,𝑞≤105)——数组𝑎的长度和漂亮测试的总数。

每个测试用例的第二行包含𝑛整数𝑎1,𝑎2,…,𝑎𝑛(1≤𝑎𝑖≤106)——𝑎数组的内容。

接下来,每个测试用例的𝑞行包含一个整数𝑠𝑖(1≤𝑠𝑖≤109)——Mike想在𝑖-th测试中获得的元素的和。

保证𝑛和𝑞的和不超过105(∑𝑛,∑𝑞≤105)。

输出
打印𝑞行,如果通过了相应的漂亮测试,每一行都包含“Yes”,反之则包含“No”。

例子
inputCopy
2
5 5
1 2 3 4 5
1
8
9
12
6
5 5
3 1 3 1 3
1
2
3.
9
11
outputCopy
是的
没有
是的
没有
是的
没有
是的
没有
是的
是的
请注意
第一个测试用例的解释:

我们可以通过以下方式获得一个和为𝑠1=1的数组:
1.1𝑎=[1、2、3、4、5),𝑚𝑖𝑑= 1 + 52 = 3,左=(1、2、3),𝑟𝑖𝑔ℎ𝑡=(4、5)。我们选择保留左边的数组。

1.2𝑎=(1、2、3),𝑚𝑖𝑑= 1 + 32 = 2,左=[1,2],𝑟𝑖𝑔ℎ𝑡=[3]。我们选择保留左边的数组。

1.3𝑎=[1、2],𝑚𝑖𝑑= 1 + 22 = 1,左=[1],𝑟𝑖𝑔ℎ𝑡=[2]。我们选择保持左数组的和等于1。

可以证明,不可能生成和为𝑠2=8的数组。
和为𝑠3=9的数组可以通过如下方式生成:
3.1𝑎=[1、2、3、4、5),𝑚𝑖𝑑= 1 + 52 = 3,左=(1、2、3),𝑟𝑖𝑔ℎ𝑡=(4、5)。我们选择保留𝑟𝑖𝑔ℎ𝑡数组,其和等于9。

可以证明,不可能生成和为𝑠4=12的数组。
我们可以用下面的方法得到一个和为𝑠5=6的数组:
5.1𝑎=[1、2、3、4、5),𝑚𝑖𝑑= 1 + 52 = 3,左=(1、2、3),𝑟𝑖𝑔ℎ𝑡=(4、5)。我们选择保持左边的和等于6。

第二个测试用例的解释:

可以证明,总和为𝑠1=1的数组是不可能生成的。
我们可以通过以下方式获得一个和为𝑠2=2的数组:
2.1𝑎=[3,1,3,1,3),𝑚𝑖𝑑= 1 + 32 = 2,左=[1],𝑟𝑖𝑔ℎ𝑡=[3,3,3]。我们选择保持左边数组的和等于2。

可以证明,总和为𝑠3=3的数组是不可能生成的。
我们可以用下面的方法得到一个和为𝑠4=9的数组:
4.1𝑎=[3,1,3,1,3),𝑚𝑖𝑑= 1 + 32 = 2,左=[1],𝑟𝑖𝑔ℎ𝑡=[3,3,3]。我们选择保留𝑟𝑖𝑔ℎ𝑡数组,其和等于9。

我们可以用零切片操作得到一个sum为𝑠5=11的数组,因为数组sum等于11。

思路:想了很久,感觉都没有好的思路来什么的,后来发现只要直接暴力就可以。。。

为什么呢,我们用前缀和维护区间和,然后每次二分查找,然后利用前缀和+map来记录是否出现,时间复杂度大概是nlogn?不太懂,不太会算递归的复杂度。我们直接将数组全部预处理完即可,之后直接查询是否存在。map就直接过了,本来还以为要用unordered_map优化。map的话,复杂度好像就是O(nlogn+qlogn),不知道算的对不对(狗头

代码:

/*Looking! The blitz loop this planet to search way
 
 Only my RAILGUN can shoot it 今すぐ
 
 身体中を  光の速さで
 
 駆け巡った確かな予感
 
 掴め! 望むものなら残さず
 
 輝ける自分らしさで
 
 信じてるよ  あの日の誓いを
 
 この瞳に光る涙それさえも  強さになるから
 
 */
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<tuple>
#include<numeric>
#include<stack>
using namespace::std;
typedef long long  ll;
int n,t;
inline __int128 read(){
    __int128 x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
inline void print(__int128 x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        print(x / 10);
    putchar(x % 10 + '0');
}

int q,w;
int a[100005];
ll s[100005];
map<ll,int>ff;
void dfs(int x,int y){
    if (x>y) {
        return;
    }
    ff[s[y]-s[x-1]]=1;
    int mdd=(a[x]+a[y])/2;
//    printf("%d\n",mdd);
    if (x==y) {
        return;
    }
    int kl=upper_bound(a+1, a+1+n, mdd)-a;
//    printf("%d\n",kl);
    if (kl<1||kl>n) {
        return;
    }
    if (kl-1>=1&&kl<=n&&kl-1<y)
        dfs(x, kl-1);
    if(n>=kl&&kl>x)
        dfs(kl, y);
}
void wanyurukong(){
    ff.clear();
    cin>>n>>q;
    for (int i =1; i<=n; i++) {
        cin>>a[i];
    }
    sort(a+1, a+1+n);
    for (int i =1; i<=n; i++) {
        s[i]=s[i-1]+a[i];
    }
    dfs(1,n);
    while (q--) {
        cin>>w;
        if (ff.count(w)) {
            printf("YES\n");
        }
        else{
            printf("NO\n");
        }
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    cin>>t;
    while (t--) {
        wanyurukong();
    }
    //wanyurukong
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值