二分(差分+思维)

二分(差分+思维)

 

 

当猜了一个数\(x\),总共有三种情况:

裁判说数大了,那么裁判说对的取值范围是(-∞,x]

裁判说数小了,那么裁判说对的取值范围是[x,+∞)

裁判说数一样,那么裁判说对的取值范围是[x,x]

 

那么我们只需要求最大有多少个区间重叠了就行了,问题就转化成了区间的修改,单点查询,可以考虑差分了。

注意题目数据\(n\)只有100000,但是所猜的数是在\(int\)范围内的,所以我们可以离散化

对于三种情况:'+': cf[1]++,cf[pos]--;  '-':cf[pos+1]++;  '.':cf[pos]++, cf[pos+1]--;

 

但是这样是错的:

比如下面这个样例我们应该输出2,如果单纯的直接离散化然后查找我们输出答案就是1

3 -

5 +

为什么会错呢:我们模拟一下上面错误的过程,最终我们的cf数组是这样的cf[1]=1,cf[2]=0;

其实这两个共同覆盖了4,但是我们并没有体现出来(如果这里讲的不太清楚,可以看看这里讲的:here

那么怎么避免这种错误呢,如果相邻数字间距大于1的话,在我们可以在其中加上任意一个数字。

AC_Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 using namespace std;
 7 typedef long long ll;
 8 #define endl '\n'
 9 const int maxn = 1e6+10;
10 const int inf = 0x3f3f3f3f;
11  
12 struct node{
13     int id;
14     char s[3];
15 }e[maxn];
16  
17 int b[maxn];
18 int cf[maxn];
19 int n;
20  
21 int main()
22 {
23  
24  
25     cin>>n;
26     for(int i=0;i<n;i++){
27         scanf("%d%s",&e[i].id,e[i].s);
28         b[i+1]=e[i].id;
29     }
30     sort(b+1,b+1+n);
31     int num=unique(b+1,b+1+n)-(b+1);
32     int reu=num;
33     for(int i=1;i<reu;i++){
34         if( b[i+1]-b[i]>1 ) b[++num]=b[i]+1;
35     }
36     sort(b+1,b+1+num);
37     for(int i=0;i<n;i++){
38         int pos=lower_bound(b+1,b+1+num,e[i].id)-b;
39         if( e[i].s[0]=='.' ){
40             cf[pos]++;
41             cf[pos+1]--;
42         }
43         else if( e[i].s[0]=='-'){
44             cf[pos+1]++;
45         }
46         else if( e[i].s[0]=='+'){
47             cf[1]++;
48             cf[pos]--;
49         }
50     }
51     int mx=-1;
52     int f=cf[1];
53     mx=f;
54     for(int i=2;i<=num;i++){
55         f=f+cf[i];
56         if( mx<f ){
57             mx=f;
58         }
59     }
60     printf("%d\n",mx);
61     return 0;
62 }

参考:here

posted @ 2020-07-25 17:24  swsyya  阅读(292)  评论(0编辑  收藏  举报

回到顶部