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
原文地址:https://www.cnblogs.com/ibilllee/p/9285966.html