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 }