【BZOJ 3165】【HEOI 2013】Segment

往区间上覆盖一次函数,做法是用线段树维护标记永久化。

每次都忘了线段树要4倍空间,第一次交总是RE,再这么手残的话考场上就真的要犯逗了。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int p = 39989;
int read(int &k) {
	k = 0; int fh = 1; char c = getchar();
	for(; c < '0' || c > '9'; c = getchar())
		if (c == '-') fh = -1;
	for(; c >= '0' && c <= '9'; c = getchar())
		k = (k << 1) + (k << 3) + c - '0';
	k = k * fh;
}
struct node {
	double k, b; int id;
	node (int xa = 0, int ya = 0, int xb = 0, int yb = 0, int num = 0) {
		id = num;
		if (xa == xb) {k == 0; b = max(ya, yb);}
		else {k = (double) (ya - yb) / (xa - xb); b = ya - xa * k;}
	}
	double get(int x) {return k * x + b;}
};
bool lessthan(node A, node B, int x) {
	if (A.k == B.k) {return A.b < B.b;}
	double a = A.get(x), b = B.get(x);
	return a == b ? A.id < B.id : a < b;
}

node T[160003];
node Q(int rt, int l, int r, int pos) {
	if (l == r) return T[rt];
	int mid = (l + r) >> 1;
	node tmp = (pos <= mid) ? Q(rt << 1, l, mid, pos) : Q(rt << 1 | 1, mid + 1, r, pos);
	return lessthan(T[rt], tmp, pos) ? tmp : T[rt];
}
void ins2(int rt, int l, int r, node se) {
	if (!T[rt].id) {T[rt] = se; return;}
	if (lessthan(T[rt], se, l)) swap(T[rt], se);
	if (l == r || T[rt].k == se.k) return;
	double x = (T[rt].b - se.b) / (se.k - T[rt].k); int mid = (l + r) >> 1;
	if (x < l || x > r) return;
	if (x <= mid) ins2(rt << 1, l, mid, T[rt]), T[rt] = se; else ins2(rt << 1 | 1, mid + 1, r, se);
}
void ins1(int rt, int l, int r, int L, int R, node se) {
	if (L <= l && r <= R) {ins2(rt, l, r, se); return;}
	int mid = (l + r) >> 1;
	if (L <= mid) ins1(rt << 1, l, mid, L, R, se);
	if (R > mid) ins1(rt << 1 | 1, mid + 1, r, L, R, se);
}

int t, la = 0, k, opt, xa, xb, ya, yb, cnt = 0;
int main() {
	read(t);
	for(; t; --t) {
		read(opt);
		if (opt == 0) {
			read(k); k = (k + la - 1) % p + 1;
			printf("%d\n", la = Q(1, 1, p, k).id);
		} else {
			read(xa); read(ya); read(xb); read(yb);
			xa = (xa + la - 1) % p + 1; xb = (xb + la - 1) % p + 1; ya = (ya + la - 1) % (int) 1E9 + 1; yb = (yb + la - 1) % (int) 1E9 + 1;
			if (xa > xb) swap(xa, xb), swap(ya, yb);
			ins1(1, 1, p, xa, xb, node(xa, ya, xb, yb, ++cnt));
		}
	}
	return 0;
}

QwQ

posted @ 2016-05-06 08:35  abclzr  阅读(204)  评论(0编辑  收藏  举报