您的位置:首页 > 其它

BJ 集训测试14 pow

2018-03-31 09:58 295 查看
http://www.elijahqi.win/archives/2836

给定2^0,2^1,2^2,2^3….2^n在%m下的数字 他们是乱序的求最小的m n<=1e5

那么首先将模数写成m=2^p*q的情况 q是一个质数 那么显然

若p!=0那么显然除了数列中除了1其他全是偶数 那么去掉1 然后整体/2 即可转化为m/2子问题

一直递归做到p=0的情况 然后把所有数中最大的奇数 最大和次大的偶数提出来验证一下即可

#include<cstdio>
#include<cctype>
#include<algorithm>
#define N 210000
#define ll unsigned long long
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline ll read(){
ll x=0,f=1;char ch=gc();
while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}
while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
return x*f;
}
int n;ll a
,b
;
inline bool check(int st,ll md){
ll j=1;for (int i=st;i<=n;++i,j<<=1,j%=md) b[i]=j;
sort(b+st,b+n+1);
for (int i=st;i<=n;++i) if(b[i]!=a[i]) return 0;
return 1;
}
inline ll gao(int st){
bool flag=0;
//for (int i=st;i<=n;++i) printf("%lld ",a[i]); puts("");
for (int i=st+1;i<=n;++i) if (a[i]&1) {flag=1;break;}
if(!flag){
for (int i=st+1;i<=n;++i) a[i]>>=1;return gao(st+1)<<1;
}ll mxo=0,mxe1=0,mxe2=0;
for (int i=st;i<=n;++i)
if (a[i]&1) mxo=max(mxo,a[i]);else
if (a[i]>mxe1) mxe2=mxe1,mxe1=a[i];
else if(a[i]>mxe2) mxe2=a[i];
if(check(st,2*mxe2-mxo)) return 2*mxe2-mxo;else return 2*mxe1-mxo;
}
int main(){
freopen("t2.in","r",stdin);
n=read();for (int i=1;i<=n;++i) a[i]=read();
sort(a+1,a+n+1);bool flag=1;
if (!a[1]){!a
?puts("1"):printf("%lld\n",a
<<1);return 0;}
for (int i=2;i<=n;++i) if (a[i]!=a[i-1]*2) {flag=0;break;}
if (flag) {printf("%lld\n",a
+1);return 0;}
printf("%lld\n",gao(1));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: