nyist 600 - 花儿朵朵
来源:互联网 发布:java 多线程 lock 编辑:程序博客网 时间:2024/04/30 04:05
题目:给定很多花的开花时间段,询问某一时间点有多少朵花儿开放。
分析:线段树、离散化。利通每朵花的开花时间段的端点值将时间轴分割成区间段,则操作以每个区间段为整体进行。分割又两种方案:1.端点各成一段,端点间各成一段;2.建立左闭右开的区间,每个区间从上一个顶点开始、到下一个顶点之前结束(开区间)。本题采用方案2,方案一需要生成4倍花儿的数量,而方案2只需要2倍花儿的数量,空间复杂度会降低一倍。注意,在每个叶子节点上建立节点[a,a],因为操作[a,b]区间需要操作[a,b)和[b,b]两个区间,所以线段树的结点数是区间的3倍(2n-1+n),而不是通常的2倍(2n-1)。
注意:在线段树的建树过程中不要使用memset,会TLE。
#include <stdio.h>#include <stdlib.h>#include <string.h>int x[100005];int y[100005];int z[200005];int s[200005];typedef struct Tnode{Tnode* Lchild;Tnode* Rchild;int Lvalue;intRvalue;int Counts;}STnode;STnode Node[600005];class Stree{private:STnode* Root;int Count;STnode* madetree( int a, int b ) {STnode* np = &Node[Count++];np->Counts = 0;np->Lvalue = a;np->Rvalue = b;if ( a < b ) {np->Lchild = madetree( a, (a+b)/2 );if ( a+1 < b )np->Rchild = madetree( (a+b)/2, b );}else np->Lchild = np->Rchild = NULL;return np;}public:Stree( int a, int b ) {Count = 0;Root = madetree( a, b );}void Insert( STnode* r, int a, int b ) {//printf("[%d %d] <%d %d>\n",r->Lvalue,r->Rvalue,a,b);if ( r->Lvalue == a && r->Rvalue == b ) {r->Counts ++;return;}int mid = (r->Lvalue+r->Rvalue)>>1;if ( b < mid || a == b ) {if ( r->Lchild ) Insert( r->Lchild, a, b );}else if ( a >= mid ) {if ( r->Rchild ) Insert( r->Rchild, a, b );}else {if ( r->Lchild ) Insert( r->Lchild, a, mid );if ( r->Rchild ) Insert( r->Rchild, mid, b );}}int Query( STnode* r, int v ) {if ( !r ) return 0;//printf("{%d %d}\n",r->Lvalue,r->Rvalue);if ( r->Lvalue == r->Rvalue )return s[r->Lvalue]==v?r->Counts:0;if ( v < s[r->Lvalue] || v >= s[r->Rvalue] )return 0;int mid = (r->Lvalue+r->Rvalue)>>1;if ( v < s[mid] || r->Lvalue+1 == r->Rvalue )return Query( r->Lchild, v )+r->Counts;else return Query( r->Rchild, v )+r->Counts;}void Insert( int a, int b ) {Insert( Root, a, b );}int Query( int v ) {Query( Root, v );}};int Map( int numb, int m ){int l = 1,r = m,mid;while ( l < r ) {mid = (l+r)>>1;if ( s[mid] < numb ) l = mid+1;else r = mid;}return r;}int cmp( const void* a, const void* b ){return *((int *)a) - *((int*)b);}int main(){int n,m,t,a,b,ans;while ( scanf("%d",&t) != EOF ) while ( t -- ) {scanf("%d%d",&n,&m);for ( int i = 0 ; i < n ; ++ i ) {scanf("%d%d",&x[i],&y[i]);z[i] = x[i];z[i+n] = y[i];}qsort( z, 2*n, sizeof( int ), cmp );int count = 0;s[++count] = z[0];for ( int i = 1 ; i < 2*n ; ++ i )if ( z[i-1] != z[i] )s[++count] = z[i];s[++count] = s[count-1]+1;Stree ST( 1, count );for ( int i = 0 ; i < n ; ++ i ) {a = Map( x[i], count );b = Map( y[i], count );ST.Insert( a, b );}for ( int i = 0 ; i < m; ++ i ) {scanf("%d",&ans);printf("%d\n",ST.Query( ans ));}}return 0;}
- nyist 600 - 花儿朵朵
- nyist 花儿朵朵 离散化 + 树状数组
- NYOJ 600 花儿朵朵
- nyoj 600 花儿朵朵
- NYOJ 600 花儿朵朵
- 花儿朵朵
- 花儿朵朵
- NYOJ 600 花儿朵朵 树状数组
- Android App 花儿朵朵
- nyoj 600 花儿朵朵 (树状数组+离散化)
- NYOJ-600 花儿朵朵【离散化+树状数组】
- 15.花儿朵朵 (15分)
- nylg 600 花儿朵朵 //离散化+树状数组或线段树
- NYOJ-600-花儿朵朵-2013年08月21日19:14:49
- 南阳oj _600花儿朵朵(树状数组插线问点+坐标离散化)
- nyist
- 那些花儿
- 那些花儿
- maven安装配置
- 看似简单的问题 静态方法和实例化方法的区别
- 解决struts验证失败后导致其他Action方法不能执行
- 必读书籍列表
- 全排列和组合
- nyist 600 - 花儿朵朵
- 学习札记: C++指向函数的指针
- Windows Message Queue(优先级队列+map)
- 数据结构实验(严蔚敏版)二叉树的建立与遍历
- C++编程规范---第11章 其它编程经验
- C++编程规范---第10章 类的继承与组合
- 正则表达式判断
- C++编程规范---第9章 类的构造函数、析构函数与赋值函数
- 正则表达式的几种字符判断(包括数字,字母组合等)