• 线段树:跳水问题


    【来源】网上流传的2017-360秋招笔试题

    【问题描述】

    【算法思路】

    直接求解会超时。使用“线段树”,节点信息为当前区段的元素个数。假设输入元素最大值为M, 建立有M个叶子节点的树,再依次插入元素并向上更新节点信息。

    【程序】

      1 #include <iostream>
      2 #include <vector>
      3 
      4 //#pragma comment(linker, "/STACK:102400000,102400000")
      5 using namespace std;
      6 struct Segment
      7 {
      8     int l, r;
      9     int value;
     10     bool lazyTag;
     11     int lazyValue;
     12     Segment() :l(0), r(0), value(INT_MAX), lazyTag(false) {};
     13 };
     14 void buildTree(vector<Segment> &tree, int node, int l, int r)
     15 {
     16     tree[node].l = l;
     17     tree[node].r = r;
     18     if (l == r) return;
     19     buildTree(tree, node << 1, l, (l + r) >> 1);
     20     buildTree(tree, (node << 1) + 1, (l + r + 1) >> 1, r);
     21     tree[node].value = tree[node << 1].value + tree[(node << 1) + 1].value;
     22 }
     23 void update(vector<Segment> &tree, int node)
     24 {
     25     if (node == 0) return;
     26     // <<1相当于*2,>>1相当于/2取整
     27     tree[node].value = tree[node << 1].value+tree[(node << 1) + 1].value;
     28     update(tree, node >> 1);
     29 }
     30 void pushDown(vector<Segment> &tree, int father)
     31 {
     32     if (tree[father].lazyTag)
     33     {
     34         int leftChild = father << 1, rightChild = (father << 1) + 1;
     35         tree[leftChild].value = (tree[leftChild].r - tree[leftChild].l + 1)*tree[father].lazyValue;
     36         tree[leftChild].lazyTag = true;
     37         tree[leftChild].lazyValue = tree[father].lazyValue;
     38         tree[rightChild].value = (tree[rightChild].r - tree[rightChild].l + 1)*tree[father].lazyValue;
     39         tree[rightChild].lazyTag = true;
     40         tree[rightChild].lazyValue = tree[father].lazyValue;
     41         tree[father].lazyTag = false;
     42     }
     43 }
     44 void updateInterval(vector<Segment> &tree, int node, int l, int r, int value)
     45 {
     46     if (tree[node].l == l&&tree[node].r == r)
     47     {
     48         tree[node].lazyTag = true;
     49         tree[node].value = (r - l + 1)*value;
     50         tree[node].lazyValue = value;
     51         return;
     52     }
     53     else {
     54         //pushDown(tree, node);
     55         if (tree[node << 1].r >= r) updateInterval(tree, node << 1, l, r, value);
     56         else if (tree[(node << 1) + 1].l <= l) updateInterval(tree, (node << 1) + 1, l, r, value);
     57         else
     58         {
     59             updateInterval(tree, node << 1, l, tree[node << 1].r, value);
     60             updateInterval(tree, (node << 1) + 1, tree[(node << 1) + 1].l, r, value);
     61         }
     62     }
     63     tree[node].value = tree[node << 1].value + tree[(node << 1) + 1].value;
     64 }
     65 
     66 int query(vector<Segment> &tree, int node, int l, int r)
     67 {
     68     if (tree[node].l == l&&tree[node].r == r) return tree[node].value;
     69     else
     70     {
     71         //pushDown(tree, node);
     72         if (tree[node << 1].r >= r) return query(tree, node << 1, l, r);
     73         else if (tree[(node << 1) + 1].l <= l) return query(tree, (node << 1) + 1, l, r);
     74         else
     75         {
     76             return query(tree, node << 1, l, tree[node << 1].r) + query(tree, (node << 1) + 1, tree[(node << 1) + 1].l, r);
     77         }
     78     }
     79 }
     80 #define MAXN 200005
     81 int A[MAXN];
     82 int main() {
     83 #ifdef DEBUG
     84     ifstream cin("in.txt");
     85     ofstream cout("out.txt");
     86     //freopen("in.txt", "r",stdin);
     87     //freopen("out.txt", "w",stdout);
     88 #endif
     89     int n=0, a, b, size = 1;
     90     int N;
     91     cin >> N;
     92     for (size_t i = 0; i < N; i++)
     93     {
     94         cin >> A[i];
     95         n = max(n, A[i]);
     96     }
     97     while (size < n) size <<= 1;
     98     vector<Segment> tree(size * 2);
     99     for (size_t i = 0; i < size; i++)
    100     {
    101         tree[i + size].value=0;
    102     }
    103     buildTree(tree, 1, 1, size);
    104     int ans;
    105     for (size_t i = 0; i < N; i++)
    106     {
    107         tree[A[i]-1 + size].value++;
    108         update(tree, (A[i]-1 + size)/2);
    109         ans = query(tree,1,A[i],size);
    110         if (!i)
    111             cout << ans - tree[A[i] - 1 + size].value;  //减去相等的个数,输出大于的个数
    112         else
    113             cout<< ' '<< ans - tree[A[i] - 1 + size].value;
    114     }
    115 
    116     return 0;
    117 }
  • 相关阅读:
    [转]使用Composer管理PHP依赖关系
    Php环境下载(PHPNow)安装
    精美的 ( Android, iPhone, iPad ) 手机界面设计素材和线框图设计工具
    八款强大的jQuery图片滑块动画插件
    JavaScript prototype.js提升JavaScript开发效率
    JS Message 网页消息提醒
    Vis.js图表插件
    动态算法学习
    GPS功能:百度路书自定义【轨迹回放】
    CSS美化页面滚动条
  • 原文地址:https://www.cnblogs.com/JesusAlone/p/7450100.html
Copyright © 2020-2023  润新知