zoukankan      html  css  js  c++  java
  • HDU 4417 【线段树+离线处理】

    http://acm.hdu.edu.cn/showproblem.php?pid=4417

    题意:找出给定区间内,有多少个数小于等于给定的数。用线段树维护的话会超时,要用到线段树的离线操作,对询问与数列都进行从小到大的排序,记录下标。从第一个询问开始,遍历数列,满足小于等于就插入到线段树中相应的位置。答案即为当前线段树中有多少个值。转换成了区间和,记录答案,最后一遍输出。

    代码如下:

      1 #include<stdio.h>
      2 #include<algorithm>
      3 const int MAXN = 1e5 + 10;
      4 using namespace std;
      5 
      6 int n, m;
      7 int ANS[MAXN];
      8 
      9 struct Node
     10 {
     11     int id, h;
     12 }node[MAXN];
     13 bool cmp1(Node a, Node b)
     14 {
     15     return a.h < b.h;
     16 }
     17 
     18 struct Tree
     19 {
     20     int l, r, num;
     21 }t[MAXN * 4];
     22 
     23 struct Query
     24 {
     25     int l, r, limit, id;
     26 }q[MAXN];
     27 bool cmp2(Query a, Query b)
     28 {
     29     return a.limit < b.limit;
     30 }
     31 
     32 void build(int l, int r, int k)
     33 {
     34     t[k].l = l, t[k].r = r, t[k].num = 0;
     35     if(l == r)
     36         return ;
     37     int mid = (l + r) / 2;
     38     build(l, mid, 2 * k);
     39     build(mid + 1, r, 2 * k + 1);
     40 }
     41 
     42 void up_date(int id, int k)
     43 {
     44     if(t[k].l == t[k].r)
     45     {
     46         t[k].num = 1;
     47         return ;
     48     }
     49     int mid = (t[k].l + t[k].r) / 2;
     50     if(id <= mid)
     51         up_date(id, 2 * k);
     52     else
     53         up_date(id, 2 * k + 1);
     54     t[k].num = t[2 * k].num + t[2 * k + 1].num;
     55 }
     56 
     57 int query(int f_l, int f_r, int k)
     58 {
     59     if(f_l <= t[k].l && f_r >= t[k].r)
     60         return t[k].num;
     61     int mid = (t[k].l + t[k].r) / 2;
     62     if(f_l > mid)
     63         return query(f_l, f_r, 2 * k + 1);
     64     else if(f_r <= mid)
     65         return query(f_l, f_r, 2 * k);
     66     else
     67     {
     68         return query(f_l, mid, 2 * k) + query(mid + 1, f_r, 2 * k + 1);
     69     }
     70 }
     71 
     72 int main()
     73 {
     74     int T, k = 1;
     75     scanf("%d", &T);
     76     while(T --)
     77     {
     78         scanf("%d%d", &n, &m);
     79         build(1, n, 1);
     80         for(int i = 1; i <= n; i ++)
     81         {
     82             scanf("%d", &node[i].h);
     83             node[i].id = i;
     84         }
     85         sort(node + 1, node + 1 + n, cmp1);
     86     //    for(int i = 1; i <= n; i ++)
     87     //        printf("%d
    ", node[i].h);
     88         printf("Case %d:
    ", k ++);
     89         for(int i = 1; i <= m; i ++)
     90         {
     91             scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].limit);
     92             q[i].l ++, q[i].r ++;
     93             q[i].id = i;
     94         }
     95         sort(q + 1, q + 1 + m, cmp2);
     96         int j = 1;
     97         for(int i = 1; i <= m; i ++)
     98         {
     99             while(node[j].h <= q[i].limit && j <= n)
    100             {
    101                 up_date(node[j].id, 1);
    102                 j ++;
    103             }
    104             ANS[q[i].id] = query(q[i].l, q[i].r, 1);
    105         }
    106         for(int i = 1; i <= m; i ++)
    107             printf("%d
    ", ANS[i]);
    108     }
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    FAT学习笔记(五)——FAQ
    FAT32学习笔记(五)——fat相关工具
    FAT学习笔记(四)——Dir Entry
    FAT学习笔记(三)--FSInfo
    zabbix介绍
    配置pxe 自动化安装centos6.7
    跳转方式用name方法的话,浏览器返回按钮点击返回时会有BUG
    FormData使用方法详解
    vue中的@click.native
    vue从后台获取数据,并导出EXCEL文件
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/11182320.html
Copyright © 2011-2022 走看看