POJ 3484 Showstopper(二分答案)
【题目链接】 http://poj.org/problem?id=3484
【题目大意】
给出n个等差数列的首项末项和公差。求在数列中出现奇数次的数。题目保证至多只有一个数符合要求。
【题解】
因为只有一个数符合要求,所以在数列中数出现次数的前缀和必定有奇偶分界线,
所以我们二分答案,计算前缀和的奇偶性进行判断,得到该数的位置。
【代码】
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long LL; const int N=500010; const LL inf=1LL<<33; LL X[N],Y[N],Z[N]; char s[60]; int n; LL cal(LL x){ LL ans=0,t; for(int i=1;i<=n;i++){ if(x<X[i])continue; t=min(x,Y[i]); ans+=(t-X[i])/Z[i]+1; }return ans; } int main(){ while(gets(s)){ X[n=1]=0; sscanf(s,"%lld %lld %lld",&X[n],&Y[n],&Z[n]); if(!X[n])continue; memset(s,0,sizeof(s)); while(gets(s),*s)n++,sscanf(s,"%lld %lld %lld",&X[n],&Y[n],&Z[n]),memset(s,0,sizeof(s)); LL l=1,r=inf,ans=0; while(l<=r){ LL mid=(l+r)>>1; if(cal(mid)&1LL)r=mid-1,ans=mid; else l=mid+1; }if(!ans)puts("no corruption"); else printf("%lld %lld\n",ans,cal(ans)-cal(ans-1)); }return 0; }
愿你出走半生,归来仍是少年