1、BZOJ 4364 [IOI2014]wall砖墙
解题思路:
维护区间最大值和最小值以及区间是否相同
加读入优化和不加读入优化
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>
using namespace std;
#define lc id << 1
#define rc id << 1 | 1
#define lson low, mid, lc
#define rson mid + 1, high, rc
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define eps 1e-9
typedef long long ll;
const int INF = 0x7fffffff;
const int maxn = 2e6 + 10;
const int maxk = 5e5 + 10;
int n, k, op, Left, Right, height;
int Max[maxn * 4], Min[maxn * 4], lazy[maxn * 4];
inline int read(void) {
int ret = 0; char c = getchar();
while (c > '9' || c < '0') { c = getchar(); }
while ('0' <= c && c <= '9') { ret = ret * 10 + c - '0'; c = getchar(); }
return ret;
}
inline void push_up(int id) { Max[id] = max(Max[lc], Max[rc]); Min[id] = min(Min[lc], Min[rc]); }
void build(int low, int high, int id) {
if (low == high) { Max[id] = 0; Min[id] = 0; lazy[id] = 0; return; }
int mid = (low + high) / 2; build(lson); build(rson);
}
inline void push_down(int id) {
if (lazy[id] == -1) { return; }
Max[lc] = lazy[id]; Min[lc] = lazy[id]; lazy[lc] = lazy[id];
Max[rc] = lazy[id]; Min[rc] = lazy[id]; lazy[rc] = lazy[id];
lazy[id] = -1;
}
void update1(int l, int r, int h, int low, int high, int id) {
if (l == low && r == high) {
if (h >= Max[id]) { Max[id] = h; Min[id] = h; lazy[id] = h; return; }
if (h <= Min[id]) { return; }
}
int mid = (low + high) / 2; push_down(id);
if (r <= mid) { update1(l, r, h, lson); }
else if (l >= mid + 1) { update1(l, r, h, rson); }
else { update1(l, mid, h, lson); update1(mid + 1, r, h, rson); }
push_up(id);
}
void update2(int l, int r, int h, int low, int high, int id) {
if (low == l && high == r) {
if (h <= Min[id]) { Max[id] = h; Min[id] = h; lazy[id] = h; return; }
if (h >= Max[id]) { return; }
}
int mid = (low + high) / 2; push_down(id);
if (r <= mid) { update2(l, r, h, lson); }
else if (l >= mid + 1) { update2(l, r, h, rson); }
else { update2(l, mid, h, lson); update2(mid + 1, r, h, rson); }
push_up(id);
}
void query(int low, int high, int id) {
if (lazy[id] != -1) { for (int i = low; i <= high; ++i) { printf("%d\n", Max[id]); } return; }
if (low == high) { printf("%d\n", Max[id]); return; }
int mid = (low + high) / 2; push_down(id); query(lson); query(rson);
}
int main() {
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // __AiR_H
n = read(); k = read(); memset(lazy, -1, sizeof(lazy));
for (int i = 0; i < k; ++i) {
op = read(); Left = read(); Right = read(); height = read(); ++Left; ++Right;
if (op == 1) { update1(Left, Right, height, 1, n, 1); }
else { update2(Left, Right, height, 1, n, 1); }
}
query(1, n, 1);
#ifdef __AiR_H
printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
return 0;
}
2、HZAU 1207 Candies
参考:http://www.cnblogs.com/jianrenfang/p/6754620.html
PS:第一道线段树区间合并,开始在查询的时候直接把两个询问结果相加了。。。然后找不出错误wa到死。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>
#include <cassert>
using namespace std;
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define eps 1e-9
#define lc id << 1
#define rc id << 1 | 1
#define lson low, mid, lc
#define rson mid + 1, high, rc
typedef long long ll;
typedef pair<int, int> pii;
struct Node { int id, B, lb, rb, len; };
const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
int T, n, m, cmd, L, R, v;
char str[maxn];
int num[maxn], lazy[maxn * 4], B[maxn * 4], lb[maxn * 4], rb[maxn * 4];
inline void push_up(int id, int low, int mid, int high) {
if (lazy[lc] == 1 && lazy[rc] == 1) { lazy[id] = 1; B[id] = 0; lb[id] = 0; rb[id] = 0; return; }
if (lazy[lc] == 2 && lazy[rc] == 2) { lazy[id] = 2; B[id] = B[lc] + B[rc]; lb[id] = B[id]; rb[id] = B[id]; return; }
B[id] = max(rb[lc] + lb[rc], max(B[lc], B[rc])); lazy[id] = 0;
lb[id] = lb[lc]; if (lb[lc] == mid - low + 1) { lb[id] += lb[rc]; }
rb[id] = rb[rc]; if (rb[rc] == high - mid) { rb[id] += rb[lc]; }
}
void build(int low, int high, int id) {
if (low == high) {
if (num[low] == 2) { B[id] = 1; lazy[id] = 2; lb[id] = 1; rb[id] = 1; }
else { B[id] = 0; lazy[id] = 1; lb[id] = 0; rb[id] = 0; } return;
}
int mid = (low + high) / 2; build(lson); build(rson); push_up(id, low, mid, high);
}
inline void push_down(int id, int low, int mid, int high) {
if (lazy[id] == 0) { return; }
if (lazy[id] == 1) {
B[lc] = 0; B[rc] = 0; lazy[lc] = 1; lazy[rc] = 1; lazy[id] = 0;
lb[rc] = 0; lb[lc] = 0; rb[lc] = 0; rb[rc] = 0;
return;
}
B[lc] = mid - low + 1; B[rc] = high - mid; lazy[lc] = 2; lazy[rc] = 2; lazy[id] = 0;
lb[lc] = B[lc]; rb[lc] = B[lc]; lb[rc] = B[rc]; rb[rc] = B[rc];
}
void update(int l, int r, int key, int low, int high, int id) {
if (l == low && r == high) {
if (key == 1) { B[id] = 0; lazy[id] = 1; lb[id] = 0; rb[id] = 0; }
else { B[id] = high - low + 1; lazy[id] = 2; lb[id] = B[id]; rb[id] = B[id]; } return;
}
int mid = (low + high) / 2; push_down(id, low, mid, high);
if (r <= mid) { update(l, r, key, lson); }
else if (l >= mid + 1) { update(l, r, key, rson); }
else { update(l, mid, key, lson); update(mid + 1, r, key, rson); }
push_up(id, low, mid, high);
}
inline Node merge(Node l, Node r) {
Node ret; ret.len = l.len + r.len; ret.lb = l.lb; ret.rb = r.rb;
if (l.lb == l.len) { ret.lb += r.lb; }
if (r.rb == r.len) { ret.rb += l.rb; }
ret.B = max(l.rb + r.lb, max(l.B, r.B));
return ret;
}
Node query(int l, int r, int low, int high, int id) {
if (l == low && r == high) { return Node{id, B[id], lb[id], rb[id], r - l + 1}; }
int mid = (low + high) / 2; push_down(id, low, mid, high);
if (r <= mid) { return query(l, r, lson); }
else if (l >= mid + 1) { return query(l, r, rson); }
Node t1 = query(l, mid, lson), t2 = query(mid + 1, r, rson);
return merge(t1, t2);
}
int main() {
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // __AiR_H
scanf("%d", &T); int Case = 0;
while (T--) {
printf("Case #%d:\n", ++Case);
scanf("%d %d", &n, &m);
scanf("%s", str); REP(i, n) { if (str[i] == 'A') { num[i + 1] = 1; } else { num[i + 1] = 2; } }
build(1, n, 1);
while (m--) {
scanf("%d %d %d", &cmd, &L, &R); if (cmd == 1) { scanf("%d", &v); }
if (cmd == 1) { update(L, R, v, 1, n, 1); }
else { printf("%d\n", query(L, R, 1, n, 1).B); }
}
}
#ifdef __AiR_H
printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
return 0;
}
3、POJ 1177 Picture
题意:
求矩形并的周长
PS:第一道扫描线,好开心啊。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>
#include <cassert>
using namespace std;
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define eps 1e-9
#define PI acos(-1.0)
#define lc id << 1
#define rc id << 1 | 1
#define lson low, mid, lc
#define rson mid + 1, high, rc
typedef long long ll;
typedef pair<int, int> pii;
struct Node {
int x, y1, y2, flag;
bool operator < (const Node& a) const {
if (x == a.x) { return flag > a.flag; } return x < a.x;
}
};
const int INF = 0x7fffffff;
const int maxn = 1e4 + 10;
vector<int> y;
int n, a, b, c, d, ans = 0, len_t = 0, line_t = 0, id1, id2;
Node node[maxn];
int cnt[maxn * 4], line[maxn * 4], lbc[maxn * 4], rbc[maxn * 4], len[maxn * 4];
int id(int x) { return lower_bound(y.begin(), y.end(), x) - y.begin() + 1; }
inline void push_up(int id, int low, int high) {
if (cnt[id]) { len[id] = y[high] - y[low - 1]; line[id] = lbc[id] = rbc[id] = 1; return; }
len[id] = len[lc] + len[rc]; lbc[id] = lbc[lc]; rbc[id] = rbc[rc];
line[id] = line[lc] + line[rc] - rbc[lc] * lbc[rc];
}
void update(int l, int r, int key, int low, int high, int id) {
if (l == low && r == high) {
if (key) { ++cnt[id]; } else { --cnt[id]; }
if (low == high && cnt[id] == 0) { len[id] = line[id] = lbc[id] = rbc[id] = 0; return; }
push_up(id, low, high); return;
}
int mid = (low + high) / 2;
if (r <= mid) { update(l, r, key, lson); }
else if (l >= mid + 1) { update(l, r, key, rson); }
else { update(l, mid, key, lson); update(mid + 1, r, key, rson); }
push_up(id, low, high);
}
int main() {
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // __AiR_H
scanf("%d", &n);
REP(i, n) {
scanf("%d %d %d %d", &a, &b, &c, &d); y.push_back(b); y.push_back(d);
node[i * 2] = Node{a, b, d, 1}; node[i * 2 + 1] = Node{c, b, d, 0};
}
sort(y.begin(), y.end()); y.erase(unique(y.begin(), y.end()), y.end());
n *= 2; sort(node, node + n); int Size = y.size() - 1;
REP(i, n) {
id1 = id(node[i].y1); id2 = id(node[i].y2);
update(id1, id2 - 1, node[i].flag, 1, Size, 1);
if (i > 0) { ans += 2 * line_t * (node[i].x - node[i - 1].x); }
ans += abs(len[1] - len_t); len_t = len[1]; line_t = line[1];
}
printf("%d\n", ans);
#ifdef __AiR_H
printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
return 0;
}
4、POJ 1151 Atlantis
题意:
求矩形并的面积,比求周长要简单。。。而且这道题数据范围很小。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>
#include <cassert>
using namespace std;
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define eps 1e-9
#define PI acos(-1.0)
#define lc id << 1
#define rc id << 1 | 1
#define lson low, mid, lc
#define rson mid + 1, high, rc
typedef long long ll;
typedef pair<int, int> pii;
struct Node {
double x, y1, y2; int flag;
bool operator < (const Node& a) const {
if (x == a.x) { return flag > a.flag; } return x < a.x;
}
};
const int INF = 0x7fffffff;
const int maxn = 200 + 10;
vector<double> y;
int n, id1, id2, Size, Case = 0;
double a, b, c, d, ans, len_t;
Node node[maxn];
int cnt[maxn * 4];
double len[maxn * 4];
int id(double x) { return lower_bound(y.begin(), y.end(), x) - y.begin() + 1; }
void build(int low, int high, int id) {
cnt[id] = 0; len[id] = 0.0; if (low == high) { return; }
int mid = (low + high) / 2; build(lson); build(rson);
}
inline void push_up(int id, int low, int high) {
if (cnt[id]) { len[id] = y[high] - y[low - 1]; return; }
len[id] = len[lc] + len[rc];
}
void update(int l, int r, int key, int low, int high, int id) {
if (l == low && r == high) {
if (key) { ++cnt[id]; } else { --cnt[id]; }
if (low == high && cnt[id] == 0) { len[id] = 0.0; return; }
push_up(id, low, high); return;
}
int mid = (low + high) / 2;
if (r <= mid) { update(l, r, key, lson); }
else if (l >= mid + 1) { update(l, r, key, rson); }
else { update(l, mid, key, lson); update(mid + 1, r, key, rson); }
push_up(id, low, high);
}
int main() {
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // __AiR_H
while (scanf("%d", &n) && n != 0) {
y.clear();
REP(i, n) {
scanf("%lf %lf %lf %lf", &a, &b, &c, &d); y.push_back(b); y.push_back(d);
node[i * 2] = Node{a, b, d, 1}; node[i * 2 + 1] = Node{c, b, d, 0};
}
sort(y.begin(), y.end()); y.erase(unique(y.begin(), y.end()), y.end());
n *= 2; sort(node, node + n); Size = y.size() - 1; build(1, Size, 1); ans = len_t = 0.0;
REP(i, n) {
id1 = id(node[i].y1); id2 = id(node[i].y2);
update(id1, id2 - 1, node[i].flag, 1, Size, 1);
if (i > 0) { ans += len_t * (node[i].x - node[i - 1].x); } len_t = len[1];
}
printf("Test case #%d\nTotal explored area: %.2f\n\n", ++Case, ans);
}
#ifdef __AiR_H
printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
return 0;
}
5、POJ 2760 End of Windless Days
参考:http://www.cppblog.com/menjitianya/archive/2011/04/03/143336.html
PS:谨防RE
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>
#include <cassert>
using namespace std;
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define eps 1e-6
#define PI acos(-1.0)
#define lc id << 1
#define rc id << 1 | 1
#define lson low, mid, lc
#define rson mid + 1, high, rc
typedef long long ll;
typedef pair<int, int> pii;
struct Node {
double x, y1, y2; int flag;
bool operator < (const Node& a) const {
if (x == a.x) { return flag > a.flag; } return x < a.x;
}
};
const int INF = 0x7fffffff;
const int maxn = 1e3 + 10;
vector<double> y;
int n, id1, id2, Size, N = 0;
double a, b, c, d, e, a_t, b_t, c_t, d_t, ans, len_t, min_x, min_y, max_x, max_y, l_x, l_y, l_h;
Node node[maxn];
int cnt[maxn * 4];
double len[maxn * 4];
int id(double x) { return lower_bound(y.begin(), y.end(), x) - y.begin() + 1; }
void build(int low, int high, int id) {
cnt[id] = 0; len[id] = 0.0; if (low == high) { return; }
int mid = (low + high) / 2; build(lson); build(rson);
}
inline void push_up(int id, int low, int high) {
if (cnt[id]) { len[id] = y[high] - y[low - 1]; return; }
len[id] = len[lc] + len[rc];
}
void update(int l, int r, int key, int low, int high, int id) {
if (l == low && r == high) {
if (key) { ++cnt[id]; } else { --cnt[id]; }
if (low == high && cnt[id] == 0) { len[id] = 0.0; return; }
push_up(id, low, high); return;
}
int mid = (low + high) / 2;
if (r <= mid) { update(l, r, key, lson); }
else if (l >= mid + 1) { update(l, r, key, rson); }
else { update(l, mid, key, lson); update(mid + 1, r, key, rson); }
push_up(id, low, high);
}
inline double cal(double a, double h1, double b, double h2) { return b - h2 * (b - a) / (h2 - h1); }
int main() {
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // __AiR_H
while (scanf("%d", &n) != EOF) {
scanf("%lf %lf %lf %lf %lf %lf %lf", &min_x, &min_y, &max_x, &max_y, &l_x, &l_y, &l_h);
y.clear(); N = 0;
REP(i, n) {
scanf("%lf %lf %lf %lf %lf", &a, &b, &c, &d, &e); if (fabs(l_h - e) < eps) { continue; }
if (a > c) { swap(a, c); } if (b > d) { swap(b, d); }
a_t = max(min_x, cal(a, e, l_x, l_h)); c_t = min(max_x, cal(c, e, l_x, l_h));
b_t = max(min_y, cal(b, e, l_y, l_h)); d_t = min(max_y, cal(d, e, l_y, l_h));
if (fabs(a_t - c_t) < eps || fabs(b_t - d_t) < eps || a_t > c_t || b_t > d_t) { continue; }
y.push_back(b_t); y.push_back(d_t);
node[N++] = Node{a_t, b_t, d_t, 1}; node[N++] = Node{c_t, b_t, d_t, 0};
}
sort(y.begin(), y.end()); y.erase(unique(y.begin(), y.end()), y.end());
sort(node, node + N); Size = y.size() - 1; ans = (max_x - min_x) * (max_y - min_y);
if (Size < 1) { printf("%.4f\n", ans); continue; }
build(1, Size, 1); len_t = 0.0;
REP(i, N) {
id1 = id(node[i].y1); id2 = id(node[i].y2);
update(id1, id2 - 1, node[i].flag, 1, Size, 1);
if (i > 0) { ans -= len_t * (node[i].x - node[i - 1].x); } len_t = len[1];
}
printf("%.4f\n", ans);
}
#ifdef __AiR_H
printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
return 0;
}