• D. Dasha and Very Difficult Problem 二分


    http://codeforces.com/contest/761/problem/D

    c[i] = b[i] - a[i],而且b[]和a[]都属于[L, R]

    现在给出a[i]原数组和c[i]的相对大小,要确定b[i]

    因为已经知道了c[i]的相对大小,那么从最小的那个开始,那个肯定是选了L的了,因为这样是最小的数,

    然后因为c[i]要都不同,那么记录最小的那个c[]的大小是mx,那么下一个就要是mx + 1,就是倒数第二小的那个。

    也就是b[i]在[L, R]中选一个数,使得b[i] - a[i] >= mx,当然这个数越小越好,为后面留空间。

    这个时候可以二分出这个数就好了。

     4 2 109
    4 109 4 7
    1 2 3 4
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <bitset>
    const int maxn = 1e5 + 20;
    int a[maxn];
    struct node {
        int id, val;
        bool operator < (const struct node & rhs) const {
            return val < rhs.val;
        }
    }c[maxn];
    map<int, bool>mp;
    int ans[maxn];
    bool check(int val, int mx, int a) {
        return val - a >= mx;
    }
    void work() {
        int n, L, R;
        scanf("%d%d%d", &n, &L, &R);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
        }
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &c[i].val);
            c[i].id = i;
        }
        sort(c + 1, c + 1 + n);
        ans[c[1].id] = L;
        int mx = L - a[c[1].id];
        int touse = L;
        for (int i = 2; i <= n; ++i) {
            mx++;
            int be = L, en = R;
            while (be <= en) {
                int mid = (be + en) >> 1;
                if (check(mid, mx, a[c[i].id])) {
                    en = mid - 1;
                } else be = mid + 1;
            }
            if (be > R) {
                cout << "-1" << endl;
                return;
            }
            ans[c[i].id] = be;
            mx = be - a[c[i].id];
        }
        for (int i = 1; i <= n; ++i) {
            cout << ans[i] << " ";
        }
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    多重背包
    摘花生
    完全背包问题
    01背包问题
    数字金字塔
    ES6 Object.assign()的用法
    umi---className设置多个样式
    npm 安装yarn
    html引入其他html的几种方式
    react打包去掉map文件
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6359718.html
Copyright © 2020-2023  润新知