一些离散化的题目

来源:互联网 发布:卫星机顶盒改网络电视 编辑:程序博客网 时间:2024/04/20 17:10

这几天做了一些离散化的题目。。。

话说这些题目一般都是先排序再建个线段树或者树状数组,或者直接拿平衡树维护一下,有时可以直接用上map或者set什么的。。。

而且很多都和几何有关。。。对于坐标的离散化很常见,一般有线段树套平衡树啊什么的。。。

还有个hnoi2012的triangle吧,我实在想不出什么复杂度靠谱的稳定算法,于是用了两个平衡树搞了一下,竟然A了。。。就是这样。。。

然后有了很多教训,比如有很多删除操作的时候千万别用map和set。。。这个慢到什么境界了。。。换手写treap速度翻三倍。。。

然后还犯了很多脑残错误,这里不贴了。。。

最后贴两道代码吧,奇长无比。。。

matrix:二维平面上依次画若干个实心矩形,每个矩形的形状要么是 A × B ,要么是 B × A 。求有多少个矩形没有被画在他之后的矩形覆盖。

写了各种二分什么的。。。常数较大,但至少不用开O2就可以只跑1s+了。。。

#include <cstdio>#include <cmath>#include <cstdlib>#include <cstring>#include <ctime>#include <cctype>#include <string>#include <map>#include <set>#include <queue>#include <algorithm>#include <fstream>#include <iostream>using namespace std;#ifdef WIN32#define fmt64 "%I64d"#else#define fmt64 "%lld"#endif#define PI M_PI#define oo 0x13131313#define iter iterator#define PB push_back#define PO pop_back#define MP make_pair#define fst first#define snd second#define cstr(a) (a).c_str()#define FOR(i, j, k) for(i = (j); i <= (k); ++i)#define ROF(i, j, k) for(i = (j); i >= (k); --i)#define FER(e, d, u) for(e = d[u]; e; e = e->n)#define FRE(i, a) for(i = (a).begin(); i != (a).end(); ++i)typedef unsigned int uint;typedef long long int64;typedef unsigned long long uint64;typedef long double real;template<class T> inline bool minim(T &a, const T &b) {return b < a ? a = b, 1 : 0;}template<class T> inline bool maxim(T &a, const T &b) {return b > a ? a = b, 1 : 0;}template<class T> inline T sqr(const T &a) {return a * a;}#define maxn 100005#define random (seed *= oo)#define updt(p) (p->size = p->c[0]->size + p->c[1]->size + 1)struct elem{elem *c[2];int v, key, size;};elem null[maxn*20], *et = null;int temp, seed = 1;void rotate(elem *&p, bool k){elem *q = p->c[!k];p->c[!k] = q->c[k], q->c[k] = p;updt(p), updt(q), p = q;}void insert(elem *&p){if (!p || p == null) *(p = ++et) = (elem){{null, null}, temp, random, 1};else if (temp == p->v) return;else if (temp < p->v) {insert(p->c[0]), updt(p);if (p->c[0]->key > p->key) rotate(p, 1);} else {insert(p->c[1]), updt(p);if (p->c[1]->key > p->key) rotate(p, 0);}}int lower_eq(elem *p, int v){if (!p) return 0;int ret = 0;for (; p != null; )if (p->v <= v) ret += p->c[0]->size + 1, p = p->c[1];else p = p->c[0];return ret;}int lower(elem *p, int v){if (!p) return 0;int ret = 0;for (; p != null; )if (p->v < v) ret += p->c[0]->size + 1, p = p->c[1];else p = p->c[0];return ret;}struct node{node *s, *t;int l, r;elem *a;};node ns[maxn*4], *nt = ns, *rt[2];node *build(int l, int r){node *p = ++nt; p->l = l, p->r = r;if (l == r) return p;p->s = build(l, (l + r) >> 1);p->t = build(((l + r) >> 1) + 1, r);return p;}int ll, rr, tx, ty;void insert(node *p){temp = ty, insert(p->a);if (p->l == p->r) return;insert(tx <= p->s->r ? p->s : p->t);}bool query(node *p){if (ll <= p->l && p->r <= rr) return lower(p->a, ty) - lower_eq(p->a, tx) > 0;if (ll <= p->s->r && query(p->s)) return 1;if (p->t->l <= rr && query(p->t)) return 1;return 0;}int n, A, B;int x[maxn], y[maxn], r[maxn];int p[maxn];int xx[maxn];inline bool cmp(int i, int j) {return x[i] < x[j];}inline void insert(int t){tx = xx[t], ty = y[t], insert(rt[r[t]]);}inline int upper(int t){int l = 1, r = n, mid;if (x[p[r]] < t) return 0;for (; l < r; )if (t < x[p[mid = (l + r) >> 1]]) r = mid;else l = mid + 1;return p[r];}inline int lower(int t){int l = 1, r = n, mid;if (x[p[r]] < t) return p[r];for (; l < r; )if (x[p[mid = (l + r) >> 1]] < t) l = mid + 1;else r = mid;return p[l - 1];}inline bool query(int t){int xt = x[t] + (r[t] ? A : B);int yt = y[t] + (r[t] ? B : A);if (!(rr = xx[lower(xt)])) return 0;ll = xx[upper(x[t] - B)], ty = yt;if (ll && ll <= rr) {tx = y[t] - A;if (query(rt[0])) return 1;}ll = xx[upper(x[t] - A)];if (ll && ll <= rr) {tx = y[t] - B;if (query(rt[1])) return 1;}return 0;}int ans;bool del[maxn];int main(){freopen("matrix.in", "r", stdin);freopen("matrix.out", "w", stdout);int i, j;cin >> n >> A >> B;FOR(i, 1, n) {scanf("%d%d%d", x+i, y+i, r+i);p[i] = i;/* discretize x */}sort(p+1, p+n+1, cmp);for (i = j = 1; i <= n; ++i) {if (i > 1 && x[p[i]] != x[p[i-1]]) ++j;xx[p[i]] = j;}rt[0] = build(1, j);rt[1] = build(1, j);insert(n);ROF(i, n-1, 1) {if (query(i)) ++ans, del[i] = 1;insert(i);}cout << n - ans << endl;FOR(i, 1, n) if (!del[i]) printf("%d ", i);return 0;}
triangle:乱搞。。。

#include <cstdio>#include <cmath>#include <cstdlib>#include <cstring>#include <ctime>#include <cctype>#include <string>#include <map>#include <set>#include <queue>#include <algorithm>#include <fstream>#include <iostream>using namespace std;#ifdef WIN32#define fmt64 "%I64d"#else#define fmt64 "%lld"#endif#define PI M_PI#define oo 0x13131313#define iter iterator#define PB push_back#define PO pop_back#define MP make_pair#define fst first#define snd second#define cstr(a) (a).c_str()#define FOR(i, j, k) for(i = (j); i <= (k); ++i)#define ROF(i, j, k) for(i = (j); i >= (k); --i)#define FER(e, d, u) for(e = d[u]; e; e = e->n)#define FRE(i, a) for(i = (a).begin(); i != (a).end(); ++i)typedef unsigned int uint;typedef long long int64;typedef unsigned long long uint64;typedef long double real;template<class T> inline bool minim(T &a, const T &b) {return b < a ? a = b, 1 : 0;}template<class T> inline bool maxim(T &a, const T &b) {return b > a ? a = b, 1 : 0;}template<class T> inline T sqr(const T &a) {return a * a;}#define maxn 100005struct data {int v; data *n;};data ds[maxn*5], *adj = ds;map<int, data*> a, b;int n, tot;int x[maxn], y[maxn];int d[maxn], q[maxn];void add(map<int, data*> &a, int x, int v){data *&e = a[x];*(++adj) = (data){v, e}, e = adj;}bool check(int k){map<int, data*>::iter I; data *e;int u = y[k], v = u + d[k];int s, t;FRE(I, b) for (s = I->fst, e = I->snd; e; e = e->n) {t = s + q[e->v];if (s <= u && v <= t) return tot = n, 0;else if (s < u && u < t) ++tot, x[tot] = x[k] + t - u;else if (s < v && v < t) ++tot, x[tot] = x[k] + v - s;}FOR(n, n+1, tot) add(a, x[n], n);return n = tot, 1;}int main(){freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);int i; cin >> n, tot = n;FOR(i, 1, n) scanf("%d%d%d", x+i, y+i, d+i), add(a, x[i], i);int pre, now; pre = now = 0;int before = -1;double ans = 0;map<int, data*>::iter I, J; data *e, *c, *cf;FRE(I, a) {pre = now, now = I->fst;int s, t, ret; s = t = ret = 0;FRE(J, b) {int tmp = J->fst;if (tmp > t) ret += t - s, s = t = tmp;for (cf = c = J->snd; c; cf = c, c = c->n)if (q[c->v] -= now - pre) maxim(t, tmp + q[c->v]);else if (c == J->snd) J->snd = c->n;else cf->n = c->n;}ret += t - s;if (~before) ans += (now - pre) * double(before + ret) / 2;for (e = I->snd; e; e = e->n)if (d[e->v] && check(e->v)) {add(b, y[e->v], e->v), q[e->v] = d[e->v];add(a, x[e->v] + d[e->v], e->v), d[e->v] = 0;}s = t = before = 0;FRE(J, b) {int tmp = J->fst;if (tmp > t) before += t - s, s = t = tmp;for (c = J->snd; c; c = c->n) maxim(t, tmp + q[c->v]);}before += t - s;}printf("%.1lf\n", ans);return 0;}



原创粉丝点击