hdu 4417 区间内比h小的数 线段树

题意求区间内比h小的数的个数

将所有的询问离线读入之后,按H从小到大排序。然后对于所有的结点也按从小到大排序,然后根据查询的H,将比H小的点加入到线段树,然后就是一个区间和.

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 using namespace std;
  8 #define for0n for(i=0;i<n;i++)
  9 #define for1n for(i=1;i<=n;i++)
 10 #define for0m for(i=0;i<m;i++)
 11 #define for1m for(i=1;i<=m;i++)
 12 #define cl(a) memset(a,0,sizeof(a))
 13 #define w12 while(scanf("%d%d",&n,&m)!=EOF)
 14 #define s12 scanf("%d%d",&n,&m);
 15 #define sa scanf("%d",a[i]);
 16 #define sb scanf("%d",b[i]);
 17 #define lson l,mid,rt<<1
 18 #define rson mid+1,r,rt<<1|1
 19 #define mid ((l+r)>>1)
 20 #define root 1,n,1
 21 const int MAXN=100015;
 22 int sum[MAXN<<2];
 23 int n,m,t;
 24 void pushup(int rt)
 25 {
 26     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
 27 }
 28 void update(int pos,int l,int r,int rt)
 29 {
 30     if(l==r)
 31     {
 32         sum[rt]+=1;
 33         return;
 34     }
 35     if(pos<=mid) update(pos,lson);
 36     else update(pos,rson);
 37     pushup(rt);
 38 }
 39 int query(int L,int R,int l,int r,int rt)
 40 {
 41     if(l>=L&&r<=R)
 42     {
 43         return sum[rt];
 44     }
 45     int ret=0;
 46     if(L<=mid)
 47     {
 48          ret+=query(L,R,lson);
 49     }
 50     if(R>mid)
 51     {
 52         ret+=query(L,R,rson);
 53     }
 54     return ret;
 55 }
 56 struct Node
 57 {
 58     int s,e,h,id;
 59     void in()
 60     {
 61         scanf("%d%d%d",&s,&e,&h);
 62         s++;
 63         e++;
 64     }
 65 }node[MAXN];
 66 struct ss
 67 {
 68     int id,v;
 69 }a[MAXN];
 70 bool cmp1(Node a,Node b)
 71 {
 72     return a.h<b.h;
 73 }
 74 bool cmp2(ss a,ss b)
 75 {
 76     return a.v<b.v;
 77 }
 78 int as[MAXN];
 79 int main()
 80 {
 81     int i,j,k;
 82     #ifndef ONLINE_JUDGE
 83     freopen("1.in","r",stdin);
 84     #endif
 85     scanf("%d",&t);
 86     int iCase=0;
 87     while(t--)
 88     {
 89         iCase++;
 90         s12;
 91         for1n
 92         {
 93             scanf("%d",&a[i].v);
 94             a[i].id=i;
 95         }
 96         sort(a+1,a+n+1,cmp2);
 97         for0m
 98         {
 99             node[i].in();
100             node[i].id=i;
101         }
102         sort(node,node+m,cmp1);
103         cl(sum);
104         i=1;j=0;
105         while(j<m)
106         {
107             while(i<=n)  //小于j.h的高度的砖块加入线段树
108             {
109                 if(a[i].v>node[j].h)break;
110                 update(a[i].id,root);
111                 i++;
112             }
113             while(j<m)
114             {
115                 if(i<=n&&node[j].h>=a[i].v)break;
116                 as[node[j].id]=query(node[j].s,node[j].e,root);
117                 j++;
118             }
119         }
120         printf("Case %d:\n",iCase);
121         for(int i=0;i<m;i++)
122           printf("%d\n",as[i]);
123     }
124     return 0;
125 }
时间: 2024-10-19 03:07:41

hdu 4417 区间内比h小的数 线段树的相关文章

hdu 4417 区间内比h小的数 划分树

二分查找最近一个比h小的数 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 #define for0n for(i=0;i<n;i++) 9 #define for1n for(i=1;i<

hdu 5023 A Corrupt Mayor&#39;s Performance Art(线段树区间更新)

#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> using namespace std; int tree[5001000],add[5001000]; int color[50]; int n,m; void pushup(int pos) { tree[pos]=tree[pos<<1]|tree[pos<<1|1]; //更新

hdu 5023 A Corrupt Mayor&#39;s Performance Art (线段树+区间更新+状压)

A Corrupt Mayor's Performance Art Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Submission(s): 699    Accepted Submission(s): 267 Problem Description Corrupt governors always find ways to get dirty money.

HDU 5023 A Corrupt Mayor&#39;s Performance Art 线段树区间更新+状态压缩

Link:  http://acm.hdu.edu.cn/showproblem.php?pid=5023 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <string> 7 #include <cmath> 8 using namesp

hdu 4893 (多校1007)Wow! Such Sequence!(线段树&amp;二分&amp;思维)

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 352    Accepted Submission(s): 104 Problem Description Recently, Doge got a funny birthday present from his new friend, Prot

HDU 5172 GTY&#39;s gay friends (预处理+线段树)

题目链接:HDU 5172 GTY's gay friends 题意:给出一串序列,询问[l,r]区间里是否存在1~l-r+1的一个排列. 思路:1~l-r+1的一个排列 等价于 [l,r]中元素互不相同且[l,r]区间和等于(1+len)*len/2(len=l-r+1). 区间和可以用前缀和来处理. 元素互不相同,记录位置i上a[i]上次出现的位置记做pre[i],再用线段树来维护区间的pre最大值,若最大值小于l说明[l,r]中元素互不相同.(区间[l,r]中的每个pre[i]小于l说明区

HDU 4027 Can you answer these queries?(线段树的单点更新+区间查询)

题目链接 题意 : 给你N个数,进行M次操作,0操作是将区间内的每一个数变成自己的平方根(整数),1操作是求区间和. 思路 :单点更新,区间查询,就是要注意在更新的时候要优化,要不然会超时,因为所有的数开几次方之后都会变成1,所以到了1不用没完没了的更新. 1 //HDU 4027 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <iostream> 6 #defi

hdu 1823 Luck and Love ,二维线段树

Luck and Love Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5282    Accepted Submission(s): 1324 Input 本题有多个测试数据,第一个数字M,表示接下来有连续的M个操作,当M=0时处理中止. 接下来是一个操作符C. 当操作符为'I'时,表示有一个MM报名,后面接着一个整数,H表示身

HDU 5649 DZY Loves Sorting(二分答案+线段树、线段树合并+线段树分割)

题意 一个 \(1\) 到 \(n\) 的全排列,\(m\) 种操作,每次将一段区间 \([l,r]\) 按升序或降序排列,求 \(m\) 次操作后的第 \(k\) 位. \(1 \leq n \leq 10^5\) 思路 两个 \(\log\) 的做法展现了二分答案的强大功能.首先二分枚举第 \(k\) 位的值,然后将小于等于它的数都变为 \(1\) ,大于它的数变为 \(0\) ,线段树可以实现对 \(01\) 序列快速的排序,按要求进行排序,然后如果第 \(k\) 位为 \(1\) 说明这