线段树 2017.4.26

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

题目:acm.hzau.edu.cn/5th.pdf

参考: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;
}

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值