题目链接: https://hihocoder.com/contest/offers55/problem/3
解题思路: 区间合并,然后没有被覆盖区间的前缀和,二分结果。或者利用离线查询,基于归并排序的思想,每次处理一批的询问。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int MAXN = 100005; 5 #define LL long long 6 //typedef long long LL; 7 struct Interval 8 { 9 LL l,r; 10 bool operator<(Interval o) 11 { 12 if (l == o.l) 13 return r < o.r; 14 return l < o.l; 15 } 16 }; 17 18 int n, m; 19 Interval a[MAXN]; 20 Interval b[MAXN]; 21 int Q; 22 23 struct Question 24 { 25 int id; 26 LL K; 27 LL ans; 28 bool operator<(Question o) 29 { 30 return id < o.id; 31 } 32 }q[MAXN]; 33 34 int cmp(Question a, Question b) 35 { 36 return a.K < b.K; 37 } 38 39 int main() 40 { 41 #ifndef ONLINE_JUDGE 42 freopen("test_3.txt", "r", stdin); 43 #endif // ONLINE_JUDGE 44 scanf("%d%d", &n, &Q); 45 for (int i = 1; i <= n; ++i) 46 { 47 scanf("%lld%lld", &a[i].l, &a[i].r); 48 } 49 sort(a+1, a+1+n); 50 m = 0; 51 LL l = a[1].l; 52 LL r = a[1].r; 53 for (int i = 2; i <= n; ++i) 54 { 55 if (a[i].l > r) 56 { 57 ++m; 58 b[m].l = l; 59 b[m].r = r; 60 l = a[i].l; 61 r = a[i].r; 62 } 63 else 64 { 65 r = max(r, a[i].r); 66 } 67 } 68 ++m; 69 b[m].l = l; 70 b[m].r = r; 71 // for (int i = 1; i <=m; ++i) 72 // { 73 // printf("Interval %lld %lld ", b[i].l, b[i].r); 74 // } 75 for (int i = 1; i <= Q; ++i) 76 { 77 scanf("%lld", &q[i].K); 78 q[i].id = i; 79 } 80 sort(q + 1, q + Q + 1, cmp); 81 LL cnt = max(0LL, b[1].l - 1); 82 int j = 1; 83 while (j <= Q && q[j].K <= cnt) 84 { 85 q[j].ans = q[j].K; 86 ++j; 87 } 88 for (int i = 2; i <= m; ++i) 89 { 90 while (j <= Q && (q[j].K - cnt <= b[i].l - b[i-1].r - 1)) 91 { 92 q[j].ans = b[i-1].r + q[j].K - cnt; 93 ++j; 94 } 95 //printf("i=%d cnt=%lld ", i, cnt); 96 cnt += b[i].l - b[i-1].r - 1; 97 } 98 //printf("i=%d cnt=%lld ", m, cnt); 99 while (j <= Q) 100 { 101 q[j].ans = b[m].r + q[j].K - cnt; 102 ++j; 103 } 104 sort(q+1, q+1+Q); 105 for (int i = 1; i <= Q; ++i) 106 { 107 printf("%lld ", q[i].ans); 108 } 109 return 0; 110 111 // pair<int, int> t(1, 2); 112 // printf(" %d %d ", t.first, t.second); 113 }