• codeforces-1461D(二分)


    codeforces1461D-Divide and Summarize

    题目链接

    题目描述:

    给定n个数组成的数列,选择一个mid值为当前数列中最大值与最小值之和除以二(向下取整),将这个数列分割为全部元素小于等于mid的一个数列和大于mid的另一个数列,数列内部的元素保持在原数列中的相对顺序,并舍去其中的一个数列,之后对剩下的那个数列进行上述重复操作,直至数列只剩下一个元素无法再分割。
    给定m个数,分别询问这m个数是否有在分割出的数列中所有元素之和与其相等。

    思路:

    观察分割方法,发现数列的原顺序对结果并没有影响,所以先对数列排序,排序后开始二分寻找分割点,模拟分割的过程,通过搜索直接求出所有的分割数列和,用map记录结果,在查询时直接离线查询即可。

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    using ll = long long;
    const ll N = 1e5+10;
    const double PI = acos(-1.0);
    #define Test ll tesnum;tesnum = read();while(tesnum--)
    
    ll read();
    ll pre[N];
    int a[N];
    map<ll,int> mp;
    int binary_search(int l, int r, int val) {
    
        while (r - l > 1) {
            int mid = (l+r)/2;
            if (a[mid] <= val) {
                l = mid;
            }else {
                r = mid;
            }
        }
        return l;
    }
    void dfs(int l,int r){
        if(l>r)return ;
        if(l==r){
            mp[a[l]]++;
            return ;
        }
        mp[pre[r]-pre[l-1]]++;
        int mid = (a[l]+a[r])/2;
        int md = binary_search(l, r+1, mid);
        if (md == r) return ;
        dfs(l,md);
        dfs(md+1,r);
    
    }
    int main() {
        int t;
        scanf("%d",&t);
        while(t--){
            int n,q;
            scanf("%d%d",&n,&q);
            for(int i = 1; i <= n; i++){
                scanf("%d",&a[i]);
            }
            sort(a+1,a+1+n);
            memset(pre,0,sizeof(pre));
            mp.clear();
            for(int i = 1; i <= n; i++){
                pre[i] = pre[i-1]+a[i];
            }
            dfs(1,n);
            for(int i = 1; i <= q; i++){
                int x;
                scanf("%d",&x);
                if(mp[x]){
                    printf("Yes
    ");
                }else{
                    printf("No
    ");
                }
            }
        }
        return "BT7274", NULL;
    }
    
    inline ll read() {
        ll hcy = 0, dia = 1;
        char boluo = getchar();
        while (!isdigit(boluo)) {
            if (boluo == '-')dia = -1;
            boluo = getchar();
        }
        while (isdigit(boluo)) {
            hcy = hcy * 10 + boluo - '0';
            boluo = getchar();
        }
        return hcy * dia;
    }
    
  • 相关阅读:
    给SEO小白看,外链和反链是什么东西?
    .NET技术webconfig加密操作
    微信清理缓存链接
    小程序学习笔记,入门(一)
    仿建设银行APP首页效果
    微商快速赚钱108招!
    如何在pycharm中安装python的插件
    opencv获取图片的尺寸
    python opencv捕获摄像头并显示内容
    Opencv的KeyPoint和DMatch数据结构
  • 原文地址:https://www.cnblogs.com/cloudplankroader/p/14176411.html
Copyright © 2020-2023  润新知