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
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; }