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;}


原创粉丝点击