hihocoder_offer收割编程练习赛55_3

题目链接: 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\n", 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\n", i, cnt);
 96         cnt += b[i].l - b[i-1].r - 1;
 97     }
 98     //printf("i=%d cnt=%lld\n", 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\n", q[i].ans);
108     }
109     return 0;
110 
111 //    pair<int, int> t(1, 2);
112 //    printf(" %d %d\n", t.first, t.second);
113 }

 

posted @ 2018-04-16 10:47  只会一点暴力  阅读(192)  评论(0编辑  收藏  举报