hdu -4325-Flowers(离散化 线段树)

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

题目意思:

给你N个花开的时间段,然后在有M个时间点,问你在这个时间点有多少花开着。

昨天刚做的一个类似的题,用线段树加离散化,然后赶紧敲,然后错八次。

最后还是没做出来。

那么思路还是线段树加离散化。

题目给的每个花开花谢的范围很大,但花的数目只有1e5,很容易就想到了离散化,然后就是用线段树去处理,找每个花开的段,最后lazy下放到

每个时间点,这样就知道每个时间点开的花数。

这题大致思路是这样的,但你会发现M次查询时,有的时间点,你在离散化时,你没将它加入,所以你在离散化后的数组里找不到这个点。当时没想到将询问的点加入一起离散化,然后各种二分,然并ruan.

下面给出代码:

  1 /*sjy*/
  2 #include<stdio.h>
  3 #include<algorithm>
  4 #include<stdlib.h>
  5 #include<string.h>
  6 #include<iostream>
  7 #include<math.h>
  8 void add(int l,int r,int k,int aa,int dd);
  9 int kr(int n,int m,int t);
 10 void lazy(int l,int r,int k);
 11 int  findd(int l,int r,int k,int aa,int dd);
 12 int cmp(const void*p,const void*q);
 13 /*int er(int n,int m,int t);*/
 14 typedef struct pp
 15 {
 16     int x;
 17     int y;
 18 }ss;
 19 int N,M,V;
 20 int tree[8*100005];//线段树数组
 21 ss a[100005];
 22 ss b[2*100005];
 23 int c[2*100005];
 24 /*int yk[2*100005];*/
 25 int kp[100005];
 26 using namespace std;
 27 int main(void)
 28 {
 29     int n,i,j,k,p,q,x,y,s;
 30     scanf("%d",&n);
 31     for(i=1; i<=n; i++)
 32     {
 33         memset(tree,0,sizeof(tree));
 34         scanf("%d %d",&N,&M);
 35         int cnt=0;
 36         int sum=-1;
 37         for(j=0; j<N; j++)
 38         {
 39             scanf("%d %d",&a[j].x,&a[j].y);
 40             b[cnt].x=a[j].x;
 41             cnt++;
 42             b[cnt].x=a[j].y;
 43             cnt++;
 44             if(sum<a[j].y)
 45             {
 46                 sum=a[j].y;
 47             }
 48         }
 49         for(j=0;j<M;j++)
 50         {
 51             scanf("%d",&kp[j]);
 52             b[cnt++].x=kp[j];
 53         }//询问的点加入离散化
 54         qsort(b,cnt,sizeof(ss),cmp);//排序离散化
 55         int vv=0;
 56         c[vv]=0;
 57         int rr=0;
 58         for(j=1; j<cnt; j++)
 59         {
 60             if(b[j].x!=b[j-1].x)
 61             {
 62                 vv++;
 63                 c[j]=vv;
 64                 rr=0;
 65                 /*yk[j]=rr;*/
 66             }
 67             else
 68             {
 69                 c[j]=vv;
 70                 /*yk[j]=rr;*/
 71             }
 72         }
 73         for(j=0; j<N; j++)
 74         {
 75             x=kr(0,cnt-1,a[j].x);//二分找点
 76             y=kr(0,cnt-1,a[j].y);
 77             add(x,y,0,0,vv);//线段数更新加段
 78         }
 79         lazy(0,vv,0);printf("Case #%d:\n",i);
 80         for(j=0;j<M;j++)
 81         {
 82             int uu=kr(0,cnt-1,kp[j]);
 83             int yy=findd(uu,uu,0,0,vv);//查询问的时间段因为为点所以l=r
 84             printf("%d\n",yy);
 85         }
 86 
 87     }
 88     return 0;
 89 
 90 }
 91 void add(int l,int r,int k,int aa,int dd)//线段数更新
 92 {
 93     if(l>dd||r<aa)
 94     {
 95         return ;
 96     }
 97     else if(l<=aa&&r>=dd)
 98     {
 99         tree[k]++;
100     }
101     else
102     {
103         add(l,r,2*k+1,aa,(aa+dd)/2);
104         add(l,r,2*k+2,(aa+dd)/2+1,dd);
105     }
106 }
107 
108 void lazy(int l,int r,int k)//最后下放操作
109 {
110     if(l==r)
111     {
112         return ;
113     }
114     else
115     {
116         tree[2*k+1]+=tree[k];
117         tree[2*k+2]+=tree[k];
118         lazy(l,(l+r)/2,2*k+1);
119         lazy((l+r)/2+1,r,2*k+2);
120     }
121 }
122 
123 
124 int  findd(int l,int r,int k,int aa,int dd)
125 {
126     if(l>dd||r<aa)
127     {
128         return 0;
129     }
130     else if(l<=aa&&r>=dd)
131     {
132         return tree[k];
133     }
134     else
135     {
136         int nx=findd(l,r,2*k+1,aa,(aa+dd)/2);
137         int ny=findd(l,r,2*k+2,(aa+dd)/2+1,dd);
138         return nx+ny;
139     }
140 
141 }
142 
143 /*int er(int n,int m,int t)
144 {
145     int y=(n+m)/2;
146     if(b[y].x==t)
147     {
148         return c[y];
149     }
150     if(m<n)
151     {
152         return -1;
153     }
154     if(m==n&&b[m].x!=t)
155     {
156         return -1;
157     }
158 
159     else if(m-n==1&&b[n].x<=t&&b[m].x>=t)
160     {
161         V=yk[n];
162         return c[n];
163     }
164     else if(b[y].x<t)
165     {
166         return er(y,m,t);
167     }
168     else return er(n,y,t);
169 
170 }*/
171 int kr(int n,int m,int t)//二分找点
172 {
173     int yy=(n+m)/2;
174     if(b[yy].x==t)
175     {
176         return c[yy];
177     }
178     else if(b[yy].x>t)
179     {
180         return kr(n,yy-1,t);
181     }
182     else return kr(yy+1,m,t);
183 }
184 int cmp(const void*p,const void*q)
185 {
186     ss*w=(ss*)p;
187     ss*ww=(ss*)q;
188 
189      return w->x-ww->x;
190 }

 

posted @ 2015-11-15 14:38  sCjTyC  阅读(315)  评论(0编辑  收藏  举报