• 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
  • 相关阅读:
    超全面的vue.js使用总结
    Python3 [字典】类型 学习笔记
    Python3 [集合]类型 学习笔记
    Python 希尔排序法
    Python 堆排序法
    Python 归并排序法
    Python 冒泡排序法
    Python 选择排序法
    Python 快速排序法(转)
    Python 插入排序法
  • 原文地址:https://www.cnblogs.com/ibilllee/p/9285966.html
Copyright © 2020-2023  润新知