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
原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6359718.html