Codechef Chef and Triangles(离散化+区间并集)

题目链接 Chef and Triangles

先排序,然后得到$m - 1$个区间:

$(a[2] - a[1], a[2] + a[1])$

$(a[3] - a[2], a[3] + a[2])$

$……$

$(a[n] - a[n - 1], a[n] + a[n - 1])$

对这些区间求交集  再和$[L, R]$求并集,最后的元素个数就是答案。

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 #define rep(i,a,b)              for(int i(a); i <= (b); ++i)
  6 #define LL              long long
  7 #define INF            1 << 30
  8 
  9 const int N = 4000000 + 10;
 10 
 11 struct node{ LL x, y;} c[N], q[N];
 12 
 13 
 14 struct Node{
 15     LL x;  int y;
 16     friend bool operator < (const Node &a, const Node &b){
 17         return (a.x == b.x) ? a.y < b.y : a.x < b.x;
 18     }
 19 } p[N];
 20 
 21 map <LL, int> mp;
 22 LL a[N], ori[N], fp[N], l, r, x, y, ans;
 23 int n, cnt, et, nx, ny, now;
 24 
 25 int f[N], h[N], d[N], ret, cnt_status, _min, _max;
 26 
 27 int main(){
 28 
 29 
 30     scanf("%d%lld%lld", &n, &l, &r);
 31     rep(i, 1, n) scanf("%lld", a + i);
 32     sort(a + 1, a + n + 1);
 33 
 34     cnt = 0; et = 0;
 35     rep(i, 1, n - 1){
 36         c[++cnt].x = a[i + 1] - a[i] + 1;
 37         p[++et].x = c[cnt].x;     p[et].y = et;
 38         c[cnt].y = a[i + 1] + a[i] - 1;
 39         p[++et].x = c[cnt].y;   p[et].y = et;
 40     }
 41     
 42     rep(i, 1, et) ori[i] = p[i].x;
 43     sort(p + 1, p + et + 1);
 44     
 45     
 46     f[p[1].y] = 1; rep(i, 2, et) f[p[i].y] = p[i].x == p[i - 1].x ? f[p[i - 1].y] : f[p[i - 1].y] + 1;
 47 
 48 
 49     rep(i, 1, et) f[i] *= 2;
 50 
 51     rep(i, 1, et){
 52         mp[ori[i]] = f[i];
 53         fp[f[i]] = ori[i];
 54     }
 55 
 56 
 57     _min = INF;
 58     _max = -_min;
 59 
 60     memset(h, 0, sizeof h);
 61     rep(i, 1, cnt){
 62         x = c[i].x, y = c[i].y;
 63         nx = mp[x], ny = mp[y];
 64 
 65         _min = min(_min, nx);
 66         _max = max(_max, ny + 6);
 67 
 68         ++h[nx], --h[ny + 1];
 69     }
 70     now = 0;
 71     rep(i, _min, _max){
 72         now += h[i];
 73         d[i] = now;
 74     }
 75 
 76 
 77     cnt_status = 0;
 78     ret = 0;
 79     rep(i, _min, _max){
 80         if (cnt_status == 0 && d[i]){
 81             ++ret;
 82             q[ret].x = fp[i];
 83             cnt_status = 1;
 84         }
 85 
 86         else
 87         if (cnt_status == 1 && d[i] == 0){
 88             q[ret].y = fp[i - 1];
 89             cnt_status = 0;
 90         }
 91     }
 92 
 93     ans = 0;
 94     rep(i, 1, ret){
 95         x = max(l, q[i].x), y = min(r, q[i].y);
 96         if (x <= y) ans += y - x + 1;
 97     }
 98 
 99     printf("%lld\n", ans);
100 
101     return 0;
102 
103 }

 

posted @ 2017-03-30 13:25  cxhscst2  阅读(233)  评论(0编辑  收藏  举报