array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 zoj 3299(区间改动+离散化) - 爱码网

题意:有n个由小木块组成的长条木块要掉下来。给出木块的左右区间,然后有给了m个木板的左右区间和高度用来接住木块,由于木块是由小木块接触组成的,也就是木板能够接住一部分的木块。剩下的会继续掉落,问最后每一个木板上有多少个小木块。
题解:这道题用线段树可解,还有还有一个比較机智的做法。
先说线段树,左右区间到3×1e7,假设用线段树解决须要离散化。

把木板从低到高排序后用一个线段树flag维护每一个区间相应的木板编号。这样高的木板就能够覆盖低木板的编号,然后用还有一个线段树sum维护每一个长条木块在每一个区间内的数量。由于有可能n个长条木块区间有重叠。所以一个区间内不会仅仅有一排小木块,那么每更新一个长条木块,相应的区间的长条木块数量加1。

最后查询每一个区间全部的小木块数量就是相应的长条木块数量乘区间长度。一開始一直MLE,然后把离散用的map换成二分查找就水过去了。
下面是线段树做法的代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 100001;
struct Board {
    int l, r, h, id;
}boa[N];
int n, m, l[N], r[N];
long long res[N];
int sum[N << 4], flag[N << 4];
vector<int> a;

bool cmp(const Board& a, const Board& b) {
    return a.h < b.h;
}

void pushdown(int k) {
    if (flag[k]) {
        flag[k * 2] = flag[k * 2 + 1] = flag[k];
        flag[k] = 0;
    }
    if (sum[k]) {
        sum[k * 2] += sum[k];
        sum[k * 2 + 1] += sum[k];
        sum[k] = 0;
    }
}

void modify1(int k, int left, int right, int l1, int r1, int x) {
    if (l1 <= left && right <= r1) {
        flag[k] = x;
        return;
    }
    pushdown(k);
    int mid = (left + right) / 2;
    if (l1 < mid)
        modify1(k * 2, left, mid, l1, r1, x);
    if (r1 > mid)
        modify1(k * 2 + 1, mid, right, l1, r1, x);
}

void modify2(int k, int left, int right, int l1, int r1) {
    if (l1 <= left && right <= r1) {
        sum[k]++;
        return;
    }
    pushdown(k);
    int mid = (left + right) / 2;
    if (l1 < mid)
        modify2(k * 2, left, mid, l1, r1);
    if (r1 > mid)
        modify2(k * 2 + 1, mid, right, l1, r1);
}

void query(int k, int left, int right) {
    if (flag[k]) {
        res[flag[k]] += (long long)sum[k] * (a[right] - a[left]);
        return;
    }
    if (left + 1 == right)
        return;
    pushdown(k);
    int mid = (left + right) / 2;
    query(k * 2, left, mid);
    query(k * 2 + 1, mid, right);
}

int main() {
    while (scanf("%d%d", &n, &m) == 2) {
        a.clear();
        memset(sum, 0, sizeof(sum));
        memset(flag, 0, sizeof(flag));
        memset(res, 0, sizeof(res));
        for (int i = 1; i <= n; i++) {
            scanf("%d%d", &l[i], &r[i]);
            a.push_back(l[i]);
            a.push_back(r[i]);
        }
        for (int i = 1; i <= m; i++) {
            scanf("%d%d%d", &boa[i].l, &boa[i].r, &boa[i].h);
            boa[i].id = i;
            a.push_back(boa[i].l);
            a.push_back(boa[i].r);
        }
        sort(a.begin(), a.end());
        a.erase(unique(a.begin(), a.end()), a.end());
        int cnt = a.size();
        sort(boa + 1, boa + 1 + m, cmp);
        for (int i = 1; i <= m; i++) {
            int pos1 = lower_bound(a.begin(), a.end(), boa[i].l) - a.begin();
            int pos2 = lower_bound(a.begin(), a.end(), boa[i].r) - a.begin();;
            modify1(1, 0, cnt - 1, pos1, pos2, boa[i].id);
        }
        for (int i = 1; i <= n; i++) {
            int pos1 = lower_bound(a.begin(), a.end(), l[i]) - a.begin();
            int pos2 = lower_bound(a.begin(), a.end(), r[i]) - a.begin();;
            modify2(1, 0, cnt - 1, pos1, pos2);
        }
        query(1, 0, cnt - 1);
        for (int i = 1; i <= m; i++)
            printf("%lld\n", res[i]);
        printf("\n");
    }
    return 0;
}

还有一种做法是看别人的题解的,速度又快代码又短(就喜欢写代码短的╮(╯▽╰)╭),不须要离散化。把全部木块和木板所在区间从左到右扫描一边,结合绘图非常好理解。

#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
const int N = 100005;
struct Board {
    int h, l, r;
    long long num;
}boa[N << 2];
struct Node {
    int st, id, v;//区间起点。区分木块还是木板。区分左右端点
}node[N << 2];
int n, m;
map<int,int> mp;//存当前处理区间内全部的木板,左值是木板高度,右值是木板相应编号

bool cmp(const Node& a, const Node& b) {
    if (a.st != b.st)
        return a.st < b.st;
    return a.v < b.v;
}

int main() {
    while (scanf("%d%d", &n, &m) == 2) {
        mp.clear();
        int cnt = 0, l, r;
        for (int i = 1; i <= n; i++) {
            scanf("%d%d", &l, &r);
            node[++cnt].st = l, node[cnt].id = 0, node[cnt].v = 1;
            node[++cnt].st = r, node[cnt].id = 0, node[cnt].v = -1;
        }
        for (int i = 1; i <= m; i++) {
            scanf("%d%d%d", &boa[i].l, &boa[i].r, &boa[i].h);
            boa[i].num = 0;
            node[++cnt].st = boa[i].l, node[cnt].id = i, node[cnt].v = 1;
            node[++cnt].st = boa[i].r, node[cnt].id = i, node[cnt].v = -1;
        }
        sort(node + 1, node + 1 + cnt, cmp);
        int pre = node[0].st, cnt1 = 0;//当前处理区间起点,当前区间的长条木块数量
        for (int i = 1; i <= cnt; i++) {
            if (mp.rbegin() != mp.rend()) {//map自己主动排序。所以map里最后一个值一定是最大的。也就是最高的木板
                int id = mp.rbegin() -> second;//右值是编号
                boa[id].num += (long long)(node[i].st - pre) * cnt1;//小木块数量是长条木块乘区间长度
            }
            if (!node[i].id) {//当前处理区间是长条木块
                if (node[i].v == 1)
                    cnt1++;//长条木块数量加1
                else
                    cnt1--;
            }
            else {//木板
                if (node[i].v == 1)//左端点增加木板
                    mp[boa[node[i].id].h] = node[i].id;
                else//右端点去掉木板
                    mp.erase(boa[node[i].id].h);
            }
            pre = node[i].st;//更新处理区间起点
        }
        for (int i = 1; i <= m; i++)
            printf("%lld\n", boa[i].num);
        printf("\n");
    }
    return 0;
}

相关文章: