CSU 1335: 高桥和低桥 (二分查找,树状数组)

Description

有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低桥之上,所以不算“淹了两次”。举例说明:

假定高桥和低桥的高度分别是5和2,初始水位为1

第一次洪水:水位提高到6(两个桥都被淹),退到2(高桥不再被淹,但低桥仍然被淹)

第二次洪水:水位提高到8(高桥又被淹了),退到3。

没错,文字游戏。关键在于“又”的含义。如果某次洪水退去之后一座桥仍然被淹(即水位不小于桥的高度),那么下次洪水来临水位提高时不能算“又”淹一次。

输入n座桥的高度以及第i次洪水的涨水水位ai和退水水位bi,统计有多少座桥至少被淹了k次。初始水位为1,且每次洪水的涨水水位一定大于上次洪水的退水水位。

Input

输入文件最多包含25组测试数据。每组数据第一行为三个整数n, m, k(1<=n,m,k<=105)。第二行为n个整数hi(2<=hi<=108),即各个桥的高度。以下m行每行包含两个整数ai和bi(1<=bi<ai<=108, ai>bi-1)。输入文件不超过5MB。

Output

对于每组数据,输出至少被淹k次的桥的个数。

Sample Input

2 2 2
2 5
6 2
8 3
5 3 2
2 3 4 5 6
5 3
4 2
5 2

Sample Output

Case 1: 1
Case 2: 3题目中有一句关键的话:初始水位为1,且每次洪水的涨水水位一定大于上次洪水的退水水位。解决办法,线段树统计次数+二分法查找优化AC代码1:
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstring>
 5 using namespace std;
 6 const int N = 1e5+10;
 7 int c[N],m,n,k,a[N];
 8 int x[N],y[N];
 9 int lowbit(int k)
10 {
11     return k&(-k);
12 }
13 void add(int k,int he)//每一项增加一个值
14 {
15     while(k>0)
16     {
17         c[k]+=he;
18         k-=lowbit(k);
19     }
20 }
21 int search(int x)
22  {
23      int tmp=x;
24      int l=1;
25      int r=n;
26      int mid;
27      while(l<r)
28      {
29          //printf("%d %d\n",l,r);
30          mid=((l+r)>>1);
31          if(a[mid]>=tmp) r=mid;
32          else l=mid+1;
33      }
34      return r;
35 }
36 int  Q(int k)
37 {
38     int query=0;
39     while(k<=n)
40     {
41      query+=c[k];
42     k+=lowbit(k);
43     }
44     return query;
45 }
46 int main()
47 {
48     int t,from,to,he,kkk=1;
49     while(~scanf("%d%d%d",&n,&m,&k))
50     {
51       memset(c,0,sizeof(c));
52       for(int i=1;i<=n;i++)
53         scanf("%d",&a[i]);
54         sort(a+1,a+n+1);
55        for(int i=1;i<=m;i++)
56        {
57            scanf("%d %d",&x[i],&y[i]);
58            if(i == 1)
59            {
60                from = i;
61                to = search(x[i]);
62            }
63           else
64           {
65               from = search(y[i-1]);
66               to   =  search(x[i]);
67           }
68             add(from,-1);
69             add(to,1);
70        }
71         int ans =0 ;
72         for(int i=1;i<=n;i++)
73         {
74             int kk =Q(i);
75             if(kk>=k)
76             ans = ans+1;
77         }
78         printf("Case %d: %d\n",kkk++,ans);
79     }
80     return 0;
81 }

AC代码二:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<string>
 5 #include<cmath>
 6 #include<cstdio>
 7 #include<queue>
 8 #define maxn 100000
 9 using namespace std;
10 int v[maxn];
11 int f[maxn];
12 int main()
13 {
14     int n,m,qu,i,j,k,sum,a,b,t,da,o=1;
15     int lp;int rp;int *p;
16     while(~scanf("%d %d %d",&n,&m,&qu))
17     {
18         memset(f,0,sizeof(f));
19             a=-1,sum=0,da=0;
20         for(i=0;i<n;i++)
21             scanf("%d",&v[i]);
22             sort(v,v+n);
23         for(i=0;i<m;i++)
24         {
25             scanf("%d %d",&b,&t);
26            lp=lower_bound(v,v+n,a+1)-v;
27            rp=lower_bound(v,v+n,b+1)-v;
28            f[lp]+=1;
29            f[rp]-=1;
30             a=t;
31         }
32         for(i=0;i<n;i++)
33         {
34             f[i]+=sum;
35             sum=f[i];
36             if(f[i]>=qu)
37             da++;
38             //cout<<f[i]<<‘\t‘;
39         }
40         printf("Case %d: %d\n",o++,da);
41     }
42     return 0;
43 }
时间: 2024-12-16 03:50:45

CSU 1335: 高桥和低桥 (二分查找,树状数组)的相关文章

TOJ 4602:高桥和低桥(二分或树状数组+二分)

描述 有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低桥之上,所以不算"淹了两次".举例说明:假定高桥和低桥的高度分别是5和2,初始水位为1第一次洪水:水位提高到6(两个桥都被淹),退到2(高桥不再被淹,但低桥仍然被淹)第二次洪水:水位提高到8(高桥又被淹了),退到3.没错,文字游戏.关键在于"又"的含义.如果某次洪水退去之后一座桥仍然被淹(即水位不小于

csu 1335: 高桥和低桥(二分+扫气球)

1335: 高桥和低桥 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 861  Solved: 248 [Submit][Status][Web Board] Description 有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低桥之上,所以不算"淹了两次".举例说明: 假定高桥和低桥的高度分别是5和2,初始水位为1 第一

CSU 1335: 高桥和低桥(扫描线) 13年省赛题

1335: 高桥和低桥 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 957  Solved: 279 [Submit][Status][Web Board] Description 有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低桥之上,所以不算"淹了两次".举例说明: 假定高桥和低桥的高度分别是5和2,初始水位为1 第一

【扫描线或树状数组】CSU 1335 高桥和低桥

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1335 [题意] 给定n座桥的高度,给定m次洪水每次的涨水水位ai和退水水位bi 询问有多少座桥被淹的次数大于等于k 洪水最开始的水位为1 [思路] 每座桥被淹一次是这样的:开始时的水位小于桥的高度,洪水最高点的水位不小于桥的高度,如有一座高度为5的桥,对于数据7 6和7 3被淹的次数都是1(看5在不在(1,7]的区间内) 把n座桥排序,每次洪水都有一个区间的桥被淹,问最后每座桥被淹多少次 这

SPOJ TEMPLEQ - Temple Queues(二分查找+树状数组)

题意: 有N个队伍(1 <= N <= 100,000),每个队伍开始有ai个人[0 <= ai<= 100,000,000],有Q个操作[0<=Q<= 500,000] 操作分为三种,1 A:表示在第A个队列加一个人. 2 X:表示求长度大于等于X队列数量.3 Y:表示所有长度大于等于Y的队列减去一个人. 题解: 把各个队列按长度排序 用差分数列来维护这个数组,这样求每个队列的长度就是求前缀和.每次求长度的复杂度是lgn,因为队列是按长度排序的,所以可以通过二分查找到

csuoj 1335: 高桥和低桥

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1335 1335: 高桥和低桥 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 802  Solved: 221[Submit][Status][Web Board] Description 有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低

【BZOJ4009】[HNOI2015]接水果 DFS序+整体二分+扫描线+树状数组

[BZOJ4009][HNOI2015]接水果 Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black,  她觉得这个游戏太简单了,于是发明了一个更加难的版本.首先有一个地图,是一棵由 n 个顶点.n-1 条边组成的树(例如图 1给出的树包含 8 个顶点.7 条边).这颗树上有 P 个盘子,每个盘子实际上是一条路径(例如图 1 中顶点 6 到顶点 8 的路径),并且每个盘子还有一个权值.第 i 个盘子

[luogu4479][BJWC2018]第k大斜率【二维偏序+二分+离散化+树状数组】

传送门 https://www.luogu.org/problemnew/show/P4479 题目描述 在平面直角坐标系上,有 n 个不同的点.任意两个不同的点确定了一条直线.请求出所有斜率存在的直线按斜率从大到小排序后,第 k 条直线的斜率为多少. 为了避免精度误差,请输出斜率向下取整后的结果.(例如: ?1.5? = 1 , ??1.5? = ?2 ) 分析 一开始打了一个暴力,10分后来改着改着成了30分,浮点误差. 正解其实很简单,我们首先逆向思考一下,如果我们假设已经有了斜率k. 如

Luogu3527 POI2011 Meteors 整体二分、树状数组、差分

传送门 比较板子的整体二分题目,时限有点紧注意常数 整体二分的过程中将时间在\([l,mid]\)之间的流星使用树状数组+差分进行维护,然后对所有国家查看一遍并分好类,递归下去,记得消除答案在\([mid+1,r]\)的询问中时间在\([l,mid]\)的流星操作的贡献 注意:可能存在某一段时间某一个国家的流星数量超过long long范围,应该当某个时候国家流星量和大于等于国家需求值时直接退出,这样可以避免这个问题. #include<bits/stdc++.h> #define INF 0