当猜了一个数(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 ' ' 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 ",mx); 61 return 0; 62 }
参考:here