hdu--5091--线段树

自己还是没有做出来= =

我去用段树 而不是点树去做了

而貌似段树不行啊。

我还没想明白 ccc

  1 #include <iostream>
  2 #include <algorithm>
  3 using namespace std;
  4
  5 int cnt;
  6 const int size = 20010;
  7 struct data
  8 {
  9     int L , R , flag , sum;
 10     int x1 , x2 , y;
 11     data(){};
 12     data( int u , int w , int v , int p ):x1(u),x2(w),y(v),flag(p){};
 13 }tree[size<<2],mat[size];
 14 int seg[size];
 15
 16 bool cmp( const data p , const data q )
 17 {
 18     if( p.y==q.y )
 19         return p.flag > q.flag;
 20     return p.y < q.y;
 21 }
 22
 23 void pushDown( int rt )
 24 {
 25     if( tree[rt].flag )
 26     {
 27         tree[rt<<1].flag += tree[rt].flag;
 28         tree[rt<<1|1].flag += tree[rt].flag;
 29         tree[rt<<1].sum += tree[rt].flag;
 30         tree[rt<<1|1].sum += tree[rt].flag;
 31         tree[rt].flag = 0;
 32     }
 33 }
 34
 35 void pushUp( int rt )
 36 {
 37     tree[rt].sum = max( tree[rt<<1].sum , tree[rt<<1|1].sum );
 38 }
 39
 40 void build( int rt , int L , int R )
 41 {
 42     int M = ( L + R ) >> 1;
 43     tree[rt].L = L , tree[rt].R = R;
 44     tree[rt].flag = tree[rt].sum = 0;
 45     if( L == R )
 46         return ;
 47     build( rt<<1 , L , M );
 48     build( rt<<1|1 , M+1 , R );
 49 }
 50
 51 void update( int rt , int L , int R , int var )
 52 {
 53     int M = ( tree[rt].L + tree[rt].R ) >> 1;
 54     if( tree[rt].L == L && tree[rt].R == R )
 55     {
 56         tree[rt].flag += var;
 57         tree[rt].sum += var;
 58         return ;
 59     }
 60     pushDown( rt );
 61     if( R<=M )
 62         update( rt<<1 , L , R , var );
 63     else if( L>=M+1 )
 64         update( rt<<1|1 , L , R , var );
 65     else
 66     {
 67         update( rt<<1 , L , M , var );
 68         update( rt<<1|1 , M+1 , R , var );
 69     }
 70     pushUp( rt );
 71 }
 72
 73 int main()
 74 {
 75     cin.sync_with_stdio(false);
 76     int n , w , h , x , y , L , R , ans;
 77     while( cin >> n >> w >> h )
 78     {
 79         if( n<0 )
 80             break;
 81         cnt = 1;
 82         for( int i = 0 ; i<n ; i++ )
 83         {
 84             cin >> x >> y;
 85             seg[cnt] = x;
 86             mat[cnt++] = data( x , x+w , y , 1 );
 87             seg[cnt] = x+w;
 88             mat[cnt++] = data( x , x+w , y+h , -1 );
 89         }
 90         sort( seg+1 , seg+cnt );
 91         sort( mat+1 , mat+cnt , cmp );
 92         cnt = unique( seg+1 , seg+cnt ) - seg;
 93         build( 1 , 1 , cnt-1 );
 94         ans = 0;
 95         for( int i = 1 ; i<=(n<<1) ; i++ )
 96         {
 97             L = lower_bound( seg+1 , seg+cnt , mat[i].x1 ) - seg;
 98             R = lower_bound( seg+1 , seg+cnt , mat[i].x2 ) - seg;
 99             update( 1 , L , R , mat[i].flag );
100             ans = max( ans , tree[1].sum );
101         }
102         cout << ans << endl;
103     }
104     return 0;
105 }

时间: 2024-08-28 21:43:48

hdu--5091--线段树的相关文章

HDU 5091 线段树扫描线

给出N个点,和一个w*h的矩形 给出N个点的坐标,求该矩形最多可以覆盖多少个点 对每个点point(x,y)右边生成对应的点(x+w,y)值为-1: 纵向建立线段树,从左到右扫描线扫一遍,遇到点则用该点的权值更新区间(y,y+h) #include "stdio.h" #include "string.h" #include "algorithm" using namespace std; struct Mark { int x,y,s; }ma

HDU 4893 线段树裸题

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

HDU 4902 线段树(区间更新)

Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 353    Accepted Submission(s): 169 Problem Description There is an old country and the king fell in love with a devil. The devil alw

hdu 4893 线段树 --- 也是两个变 类似双标记

http://acm.hdu.edu.cn/showproblem.php?pid=4893 开始的时候,我按双标记,WA了一下午,搞不定,我是用的两个标记add--表示当前结点中有值发生变化,flag,斐波那契的懒惰标记,但是估计是我自己处理的有问题,一直不对 参考了别人的代码,写法还是很不错的,Add变量维护的是,完全变成Fibonacci的时候的和,---回头我再重新写一遍 #include <cstdio> #include <cstring> #include <a

HDU 4902 线段树||暴力

给定一个序列,两种操作 1:把一段变成x. 2:把一段每个数字,如果他大于x,就变成他和x的gcd,求变换完后,最后的序列. 线段树解法:用lazy标记下即可,优化方法还是很巧妙的, Accepted 4902 515MS 3308K 1941 B C++ #include "stdio.h" #include "string.h" struct node { int l,r,x;// 在叶子节点代表值,树节点代表成端更新的lazy操作. }data[400010]

HDU 4302 线段树单点更新,维护区间最大最小值

http://acm.hdu.edu.cn/showproblem.php?pid=4302 Problem Description Holedox is a small animal which can be considered as one point. It lives in a straight pipe whose length is L. Holedox can only move along the pipe. Cakes may appear anywhere in the p

HDU 3397 线段树 双懒惰标记

这个是去年遗留历史问题,之前思路混乱,搞了好多发都是WA,就没做了 自从上次做了大白书上那个双重懒惰标记的题目,做这个就思路很清晰了 跟上次大白上那个差不多,这个也是有一个sets标记,代表这个区间全部置为0或者1,没有置位的时候为-1 还有个rev标记,代表翻转操作,0代表当前不翻,1代表当前翻 要注意一下优先级,发现有不同的弄法,我是这个弄得,有set操作的时候,set标记设值,并把当前节点的rev标记设为0,因为不管要不要rev,当前set操作肯定直接覆盖了 rev操作不改变set操作,在

hdu 2795 线段树--点更新

http://acm.hdu.edu.cn/showproblem.php?pid=2795 多校的第一场和第三场都出现了线段树,比赛期间没做,,这两天先做几道热身下,然后31号之前把那两道多校的线段树都搞了,这是一道热身题 关键是建模: 首先一定看清楚题目构造的场景,看有什么特点--------会发现,如果尽量往左上放置的话,那么由于 the i-th announcement is a rectangle of size 1 * wi.,完全可以对h建立线段树,表示一行,结点里的l,r就表示

HDU 1698 线段树(区间染色)

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 16255    Accepted Submission(s): 8089 Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing f

HDU 3642 线段树+离散化+扫描线

题意:给你N个长方体的左下角和右上角坐标,问你空间中有多少体积是被大于两个不同的立方体覆盖的.x,y~10^6 z~500 考虑到给的z比较小,所以可以直接枚举z,然后跑二维的扫描线就好. 关于处理被不同的线段覆盖三次的问题,可以维护四个信息,cnt,once,twice,more,然后相互推出结果就好. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> #