Showstopper [POJ3484] [二分] [思维]

Posted ibilllee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Showstopper [POJ3484] [二分] [思维]相关的知识,希望对你有一定的参考价值。

Description

给你n个数列,问哪一个数字在所有的数列中出现了奇数次(最多一个)。

 

Sample Input

1 10 1
2 10 1

1 10 1
1 10 1

1 10 1
4 4 1
1 5 1
6 10 1

Sample Output

1 1
no corruption
4 3

 

Analysis

我们假装按大小排好了每个数,然后我们发现,如果统计每个数出现的次数,要求的数X是奇数,其他的是偶数,那么记录前缀和,X之前全为偶数(偶+偶+...+偶=偶),X及X以后都是奇数(奇+偶=奇),那我们就可以按照这个规律二分了。

这道题还是蛮有意思的,如果奇数和偶数对掉的话,这道题就不可做了。

 

Code 

技术分享图片
 1 #include<set>
 2 #include<map>
 3 #include<queue>
 4 #include<stack>
 5 #include<cmath>
 6 #include<cstdio>
 7 #include<cstring>
 8 #include<iostream>
 9 #include<algorithm>
10 #define RG register int
11 #define rep(i,a,b)    for(RG i=a;i<=b;++i)
12 #define per(i,a,b)    for(RG i=a;i>=b;--i)
13 #define ll long long
14 #define inf 0x8f8f8f8f8f
15 #define maxn 100005
16 using namespace std;
17 ll X[maxn],Y[maxn],Z[maxn],cnt;
18 char s[maxn];
19 inline int read()
20 {
21     int x=0,f=1;char c=getchar();
22     while(c<0||c>9){if(c==-)f=-1;c=getchar();}
23     while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
24     return x*f;
25 }
26 
27 int judge(ll lim)
28 {
29     ll sum=0;
30     rep(i,1,cnt)
31     {
32         if(lim<X[i])    continue;
33         sum+=(min(Y[i],lim)-X[i])/Z[i]+1;
34     }
35     return sum&1;
36 }
37 
38 ll cal(ll lim)
39 {
40     ll sum=0;
41     rep(i,1,cnt)
42     {
43         if(lim<X[i])    continue;
44         sum+=(min(Y[i],lim)-X[i])/Z[i]+1;
45     }
46     return sum;
47 }
48 
49 void work()
50 {
51     ll l=1,r=inf,mid,ans=-1;
52     while(l<=r)
53     {
54         mid=(l+r)>>1;
55         if(judge(mid))    ans=mid,r=mid-1;
56         else            l=mid+1;
57     }
58     if(ans==-1)    puts("no corruption");
59     else
60     {
61         printf("%lld %lld
",ans,cal(ans)-cal(ans-1));
62     }
63 }
64 
65 int main()
66 {
67     while(gets(s)!=NULL)
68     {
69         if(!strlen(s))
70         {
71             if(!cnt)    continue;
72             work();cnt=0;
73         }
74         else
75         {
76             ++cnt;
77             sscanf(s,"%lld %lld %lld",&X[cnt],&Y[cnt],&Z[cnt]);
78         }
79     }
80     if(cnt) work();
81     return 0;
82 }
View Code

 

以上是关于Showstopper [POJ3484] [二分] [思维]的主要内容,如果未能解决你的问题,请参考以下文章

POJ3484 Showstopper (二分+字符串处理)

Showstopper [POJ3484] [二分] [思维]

poj 3484 Showstopper

POJ 1064 1759 3484 3061 (二分搜索)

POJ 1064 1759 3484 3061 (二分搜索)

poj3579 二分搜索+二分查找