HDU 5722 Jewelry
矩形面积并。
需要转化一下思路:记录每一个位置的数以及位置。
对数字进行从小到大排序,数字一样的按位置从小到大排。
这样,一样的数就在一起了。连续的相同的x个数就可以构成很多解,这些解对应于二维平面上某矩形内整点个数(包括边界)。
这样就处理出很多很多的矩形,因为重复只能计算一次,所以可以采用矩形面积并计算。
PS:计算整点个数的话,可以讲每一个矩形的左下角左边-1 -1,这样就直接当面积来算就可以了。
#include <cstdio> #include <cstring> #include <cctype> #include <algorithm> using namespace std; #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 const long long maxn = 200000 + 10; struct XX { long long num; long long pos; }s[maxn]; long long cnt[maxn << 2]; long long sum[maxn << 2]; long long X[maxn]; struct Seg { long long h, l, r; long long s; Seg(){} Seg(long long a, long long b, long long c, long long d) : l(a), r(b), h(c), s(d) {} bool operator < (const Seg &cmp) const { return h < cmp.h; } }ss[maxn]; void PushUp(long long rt, long long l, long long r) { if (cnt[rt]) sum[rt] = X[r + 1] - X[l]; else if (l == r) sum[rt] = 0; else sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; } void update(long long L, long long R, long long c, long long l, long long r, long long rt) { if (L <= l && r <= R) { cnt[rt] += c; PushUp(rt, l, r); return; } long long m = (l + r) >> 1; if (L <= m) update(L, R, c, lson); if (m < R) update(L, R, c, rson); PushUp(rt, l, r); } long long Bin(long long key, long long n, long long X[]) {//离散化 long long l = 0, r = n - 1; while (l <= r) { long long m = (l + r) >> 1; if (X[m] == key) return m; if (X[m] < key) l = m + 1; else r = m - 1; } return -1; } bool cmp(const XX&a, const XX&b) { if (a.num == b.num) return a.pos<b.pos; return a.num<b.num; } int main() { long long T, sz, h; scanf("%lld", &T); while (T--){ scanf("%lld%lld", &sz, &h); for (long long i = 1; i <= sz; i++) { scanf("%lld", &s[i].num); s[i].pos = i; } sort(s + 1, s + 1 + sz, cmp); long long m = 0; for (long long i = 1; i <= sz; i++) { if (i + h - 1>sz) break; if (s[i].num != s[i + h - 1].num) continue; long long Lmin, Lmax, Rmin, Rmax; if (i == 1 || s[i - 1].num != s[i].num) Lmin = 1; else Lmin = s[i - 1].pos + 1; Lmax = s[i].pos; Rmin = s[i + h - 1].pos; if (i + h -1 == sz || s[i + h].num != s[i + h - 1].num) Rmax = sz; else Rmax = s[i + h].pos - 1; long long x1 = Lmin - 1, y1 = Rmin - 1, x2 = Lmax, y2 = Rmax; long long a = x1, b = y2, c = x2, d = y1; X[m] = a; ss[m++] = Seg(a, c, b, 1); X[m] = c; ss[m++] = Seg(a, c, d, -1); } sort(X, X + m); sort(ss, ss + m); long long k = 1; for (long long i = 1; i < m; i++) { if (X[i] != X[i - 1]) X[k++] = X[i]; } memset(cnt, 0, sizeof(cnt)); memset(sum, 0, sizeof(sum)); long long ret = 0; for (long long i = 0; i < m - 1; i++) { long long l = Bin(ss[i].l, k, X); long long r = Bin(ss[i].r, k, X) - 1; if (l <= r) update(l, r, ss[i].s, 0, k - 1, 1); ret += sum[1] * (ss[i + 1].h - ss[i].h); } printf("%lld\n", ret); } return 0; }