1、Codeforces 272C Dima and Staircase
解题思路:
区间更新
#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 <bitset>
#include <ctime>
using namespace std;
#define REP(i, n) for (ll i = 0; i < (n); ++i)
#define lson low, mid, _id<<1
#define rson mid+1, high, _id<<1|1
typedef long long ll;
const ll mod = 1e9 + 7;
const ll INF = 0x7fffffff;
const ll maxn = 1e5 + 10;
ll n, m, w, h, ans;
ll a[maxn];
ll tree[4*maxn], lazy[4*maxn];
void build(ll low, ll high, ll _id);
void push_up(ll _id);
void update(ll Left, ll Right, ll val, ll low, ll high, ll _id);
void push_down(ll _id);
ll query(ll Left, ll Right, ll low, ll high, ll _id);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
scanf("%I64d", &n);
for (ll i = 1; i <= n; ++i) {
scanf("%I64d", &a[i]);
}
build(1, n, 1);
scanf("%I64d", &m);
while (m--) {
scanf("%I64d %I64d", &w, &h);
ans = query(1, w, 1, n, 1);
printf("%I64d\n", ans);
update(1, w, ans + h, 1, n, 1);
}
return 0;
}
ll query(ll Left, ll Right, ll low, ll high, ll _id)
{
if (low == Left && high == Right) {
if (lazy[_id]) {
return lazy[_id];
}
return tree[_id];
}
push_down(_id);
ll mid = (low + high) >> 1;
if (Right <= mid) {
return query(Left, Right, lson);
} else if (Left > mid) {
return query(Left, Right, rson);
} else {
return max(query(Left, mid, lson), query(mid + 1, Right, rson));
}
push_up(_id);
}
void update(ll Left, ll Right, ll val, ll low, ll high, ll _id)
{
if (low == Left && high == Right) {
tree[_id] = lazy[_id] = val;
return;
}
push_down(_id);
ll mid = (low + high) >> 1;
if (Right <= mid) {
update(Left, Right, val, lson);
} else if (Left > mid) {
update(Left, Right, val, rson);
} else {
update(Left, mid, val, lson), update(mid + 1, Right, val, rson);
}
push_up(_id);
}
void push_down(ll _id)
{
if (lazy[_id]) {
tree[_id] = lazy[_id];
tree[_id<<1] = lazy[_id], tree[_id<<1|1] = lazy[_id];
lazy[_id<<1] = lazy[_id], lazy[_id<<1|1] = lazy[_id];
lazy[_id] = 0;
}
}
void build(ll low, ll high, ll _id)
{
if (low == high) {
tree[_id] = a[low];
return;
}
ll mid = (low + high) >> 1;
build(lson), build(rson);
push_up(_id);
}
void push_up(ll _id)
{
tree[_id] = max(tree[_id<<1], tree[_id<<1|1]);
}
2、Codeforces 356A Knight Tournament
解题思路:
参考:http://www.cnblogs.com/dashuzhilin/p/4535178.html
刚开始写按照题目所给次序更新(写起来好麻烦的样子...调了好久), TLE on test 37 了...QAQ
后来看题解发现只要按照相反次序更新就可以了
#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 <bitset>
#include <ctime>
using namespace std;
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define lson low, mid, _id<<1
#define rson mid+1, high, _id<<1|1
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;
const ll mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 3e5 + 10;
int n, m, cnt = 0;
int l[maxn], r[maxn], x[maxn];
int lazy[4*maxn];
void update(int Left, int Right, int val, int low, int high, int _id);
void push_down(int _id);
void query(int low, int high, int _id);
void push_up(int _id);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; ++i) {
scanf("%d %d %d", &l[i], &r[i], &x[i]);
}
for (int i = m; i >= 1; --i) {
if (l[i] < x[i]) {
update(l[i], x[i] - 1, x[i], 1, n, 1);
}
if (r[i] > x[i]) {
update(x[i] + 1, r[i], x[i], 1, n, 1);
}
}
query(1, n, 1);
printf("\n");
return 0;
}
void query(int low, int high, int _id)
{
if (lazy[_id]) {
for (int i = low; i <= high; ++i) {
printf(++cnt == 1 ? "%d" : " %d", lazy[_id]);
}
return;
}
if (low == high) {
printf(++cnt == 1 ? "0" : " 0");
return;
}
int mid = (low + high) >> 1;
query(lson), query(rson);
}
void update(int Left, int Right, int val, int low, int high, int _id)
{
if (low == Left && Right == high) {
lazy[_id] = val;
return;
}
push_down(_id);
int mid = (low + high) >> 1;
if (Right <= mid) {
update(Left, Right, val, lson);
} else if (Left > mid) {
update(Left, Right, val, rson);
} else {
update(Left, mid, val, lson), update(mid + 1, Right, val, rson);
}
}
void push_down(int _id)
{
if (lazy[_id]) {
lazy[_id<<1] = lazy[_id], lazy[_id<<1|1] = lazy[_id];
lazy[_id] = 0;
}
}
3、ZOJ 2301 Color the Ball
离散化很优美啊!
#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 lson low, mid, _id << 1
#define rson mid + 1, high, _id << 1 | 1
typedef long long ll;
typedef pair<int, int> pii;
struct Node { int x, y, z; };
const int INF = 0x7fffffff;
const int maxn = 1e6;
int N;
int l[maxn], r[maxn], key[maxn];
char cmd[2];
int tree[maxn];
vector<int> v;
vector<pii> ans;
int id(int x) { return lower_bound(v.begin(), v.end(), x) - v.begin() + 1; }
void update(int Left, int Right, int color, int low, int high, int _id);
void query(int low, int high, int _id);
int real(int x) { return v[x - 1]; }
int main() {
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // __AiR_H
while (scanf("%d", &N) != EOF) {
if (N <= 0) { printf("Oh, my god\n"); continue; }
v.clear(); memset(tree, -1, sizeof(tree)); ans.clear();
for (int i = 0; i < N; ++i) {
scanf("%d %d %s", &l[i], &r[i], cmd);
if (cmd[0] == 'w') { key[i] = 1; }
else { key[i] = -1; }
v.push_back(l[i]); v.push_back(r[i]);
if (l[i] > 1) { v.push_back(l[i] - 1); } v.push_back(r[i] + 1);
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
for (int i = 0; i < N; ++i) { update(id(l[i]), id(r[i]), key[i], 1, (int)v.size(), 1); }
query(1, (int)v.size(), 1);
if ((int)ans.size() == 0) { printf("Oh, my god\n"); continue; }
int Max = real(ans[0].second) - real(ans[0].first), ans_l = ans[0].first, ans_r = ans[0].second;
int l_t = ans[0].first, r_t = ans[0].second;
for (int i = 1; i < (int)ans.size(); ++i) {
if (ans[i].first - 1 == ans[i - 1].second) {
r_t = ans[i].second;
} else {
l_t = ans[i].first; r_t = ans[i].second;
}
if (real(r_t) - real(l_t) > Max) { Max = real(r_t) - real(l_t); ans_l = l_t; ans_r = r_t; }
}
printf("%d %d\n", real(ans_l), real(ans_r));
}
#ifdef __AiR_H
printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
return 0;
}
void query(int low, int high, int _id) {
if (tree[_id]) {
if (tree[_id] == 1) { ans.push_back(make_pair(low, high)); }
return;
}
int mid = low + (high - low) / 2;
query(lson); query(rson);
}
void update(int Left, int Right, int color, int low, int high, int _id) {
if (tree[_id] == color) { return; }
if (low == Left && high == Right) { tree[_id] = color; return; }
int mid = low + (high - low) / 2;
if (tree[_id]) { tree[_id << 1] = tree[_id]; tree[_id << 1 | 1] = tree[_id]; tree[_id] = 0; }
if (Left > mid) { update(Left, Right, color, rson); }
else if (Right <= mid) { update(Left, Right, color, lson); }
else { update(Left, mid, color, lson); update(mid + 1, Right, color, rson); }
}
4、HDU 5306 Gorgeous Sequence
参考:
《区间最值操作与历史最值问题》杭州学军中学 吉如一
http://www.cnblogs.com/shenben/p/6641984.html
#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;
const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
int T, n, m, cmd, x, y, t;
int a[maxn], Max[maxn * 4], second[maxn * 4], num[maxn * 4];
ll sum[maxn * 4];
inline void push_up(int _id) {
sum[_id] = sum[lc] + sum[rc]; Max[_id] = max(Max[lc], Max[rc]); num[_id] = 0;
if (Max[_id] == Max[lc]) { num[_id] += num[lc]; }
if (Max[_id] == Max[rc]) { num[_id] += num[rc]; }
second[_id] = max(second[lc], second[rc]);
if (Max[lc] != Max[rc]) { second[_id] = max(second[_id], min(Max[lc], Max[rc])); }
}
inline void push_down(int _id) {
if (Max[_id] < Max[lc]) { sum[lc] += (ll)(Max[_id] - Max[lc]) * num[lc]; Max[lc] = Max[_id]; }
if (Max[_id] < Max[rc]) { sum[rc] += (ll)(Max[_id] - Max[rc]) * num[rc]; Max[rc] = Max[_id]; }
}
void build(int low, int high, int _id) {
if (low == high) { Max[_id] = a[low]; sum[_id] = a[low]; num[_id] = 1; second[_id] = 0; return; }
int mid = (low + high) / 2; build(lson); build(rson); push_up(_id);
}
int query_max(int Left, int Right, int low, int high, int _id) {
if (low == Left && high == Right) { return Max[_id]; }
int mid = (high + low) / 2; push_down(_id);
if (Right <= mid) { return query_max(Left, Right, lson); }
else if (Left >= mid + 1) { return query_max(Left, Right, rson); }
else { return max(query_max(Left, mid, lson), query_max(mid + 1, Right, rson)); }
}
ll query_sum(int Left, int Right, int low, int high, int _id) {
if (low == Left && high == Right) { return sum[_id]; }
int mid = (high + low) / 2; push_down(_id);
if (Right <= mid) { return query_sum(Left, Right, lson); }
else if (Left >= mid + 1) { return query_sum(Left, Right, rson); }
else { return query_sum(Left, mid, lson) + query_sum(mid + 1, Right, rson); }
}
void update(int Left, int Right, int key, int low, int high, int _id) {
if (key >= Max[_id]) { return; }
if (low == high) { sum[_id] += (ll)key - Max[_id]; Max[_id] = key; return; }
if (Left == low && Right == high && key > second[_id]) {
sum[_id] += (ll)num[_id] * (key - Max[_id]); Max[_id] = key; return;
}
int mid = (low + high) / 2; push_down(_id);
if (Right <= mid) { update(Left, Right, key, lson); }
else if (Left >= mid + 1) { update(Left, Right, key, rson); }
else { update(Left, mid, key, lson); update(mid + 1, Right, key, rson); }
push_up(_id);
}
int main() {
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // __AiR_H
scanf("%d", &T);
while (T--) {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); }
build(1, n, 1);
while (m--) {
scanf("%d %d %d", &cmd, &x, &y);
if (cmd == 1) { printf("%d\n", query_max(x, y, 1, n, 1)); }
else if (cmd == 2) { printf("%I64d\n", query_sum(x, y, 1, n, 1)); }
else {
scanf("%d", &t); update(x, y, t, 1, n, 1);
}
}
}
#ifdef __AiR_H
printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
return 0;
}
5、Codeforces 444C DZY Loves Colors
参考:
《小清新线段树》吉如一
http://blog.csdn.net/kalilili/article/details/46038733
#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;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int lazy[maxn * 4];
ll add[maxn * 4], sum[maxn * 4];
ll t;
int n, m, l, r, x, type;
inline void push_up(int _id) {
sum[_id] = sum[lc] + sum[rc];
if (lazy[lc] == lazy[rc]) { lazy[_id] = lazy[lc]; }
}
void build(int low, int high, int _id) {
if (low == high) { lazy[_id] = low; return; }
int mid = low + (high - low) / 2; build(lson); build(rson);
}
inline void push_down(int _id, int low, int mid, int high) {
if (lazy[_id] == 0) { return; }
add[lc] += add[_id]; sum[lc] += add[_id] * (mid - low + 1);
add[rc] += add[_id]; sum[rc] += add[_id] * (high - mid);
add[_id] = 0;
lazy[lc] = lazy[_id]; lazy[rc] = lazy[_id]; lazy[_id] = 0;
}
void update(int Left, int Right, int key, int low, int high, int _id) {
if (low == high) { sum[_id] += abs(lazy[_id] - key); lazy[_id] = key; return; }
if (Left == low && high == Right && lazy[_id]) {
t = abs(lazy[_id] - key); add[_id] += t; lazy[_id] = key;
sum[_id] += t * (high - low + 1); return;
}
int mid = low + (high - low) / 2; push_down(_id, low, mid, high);
if (Right <= mid) { update(Left, Right, key, lson); }
else if (Left >= mid + 1) { update(Left, Right, key, rson); }
else { update(Left, mid, key, lson); update(mid + 1, Right, key, rson); }
push_up(_id);
}
ll query(int Left, int Right, int low, int high, int _id) {
if (Left == low && Right == high) { return sum[_id]; }
int mid = low + (high - low) / 2; push_down(_id, low, mid, high);
if (Right <= mid) { return query(Left, Right, lson); }
else if (Left >= mid + 1) { return query(Left, Right, rson); }
else { return query(Left, mid, lson) + query(mid + 1, Right, rson); }
}
int main() {
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out2.txt", "w", stdout);
#endif // __AiR_H
scanf("%d %d", &n, &m);
build(1, n, 1);
while (m--) {
scanf("%d %d %d", &type, &l, &r);
if (type == 1) {
scanf("%d", &x); update(l, r, x, 1, n, 1);
} else {
printf("%I64d\n", query(l, r, 1, n, 1));
}
}
#ifdef __AiR_H
printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
return 0;
}