69,371
社区成员
发帖
与我相关
我的任务
分享
#include <stdio.h>
#include <assert.h>
#include <string.h>
#define DEBUG
#ifdef DEBUG
#include <time.h>
#endif
enum{LEN=32};
// a+=b
void add(unsigned int*a,size_t *asz,const unsigned int*b,size_t bsz);
// a*=b
void mul(unsigned int*a,size_t *size,unsigned long long b);
// a%=b
void rem(unsigned int *a,size_t *asz,const unsigned int*b,size_t bsz);
// ax+by=g -> return x
unsigned long long exgcd(const unsigned int*a,size_t size,unsigned long long b);
int main()
{
unsigned long long mi[8],ai[8],result;
unsigned int Mi[8][LEN],M[LEN];
size_t i,j,Mi_size[8]={0},M_size=0;
#ifdef DEBUG
clock_t tim;
#endif
for(i=0;i<8;++i)
scanf("%llu",mi+i);
for(i=0;i<8;++i)
scanf("%llu",ai+i);
#ifdef DEBUG
tim=clock();
#endif
for(i=0;i<8;++i)
mul(M,&M_size,mi[i]);
for(i=0;i<8;++i)
for(j=0;j<8;++j)
if(i!=j)
mul(Mi[i],Mi_size+i,mi[j]);
for(i=0;i<8;++i)
{
unsigned long long x=exgcd(Mi[i],Mi_size[i],mi[i]);
mul(Mi[i],Mi_size+i,x);
mul(Mi[i],Mi_size+i,ai[i]);
}
for(i=1;i<8;++i)
add(Mi[0],Mi_size,Mi[i],Mi_size[i]);
rem(Mi[0],Mi_size,M,M_size);
assert(Mi_size[0]<=2);
switch(Mi_size[0])
{
case 0:result=0;break;
case 1:result=Mi[0][0];break;
case 2:result=*(unsigned long long*)Mi[0];break;
}
if(M_size<=2)
{
for(i=1;i<8;++i)
if(mi[0]<mi[i])
mi[0]=mi[i];
if(result<mi[0])
{
unsigned long long MM=0;
switch(M_size)
{
case 0:MM=0;break;
case 1:MM=M[0];break;
case 2:MM=*(unsigned long long*)M;break;
}
result+=MM;
}
}
printf("%llu\n",result);
#ifdef DEBUG
printf("time:%gs\n",(double)(clock()-tim)/CLOCKS_PER_SEC);
#endif
return 0;
}
void add(unsigned int*a,size_t *asz,const unsigned int*b,size_t bsz)
{
unsigned int v[LEN]={0};
size_t vsz=0;
unsigned long long r=0;
while(vsz<*asz||vsz<bsz)
{
if(vsz<*asz)
r+=a[vsz];
if(vsz<bsz)
r+=b[vsz];
v[vsz++]=(unsigned int)r;
r>>=32;
}
if(r)
v[vsz++]=(unsigned int)r;
memcpy(a,v,sizeof v);
*asz=vsz;
assert(*asz<LEN);
}
void mul(unsigned int*a,size_t *size,unsigned long long b)
{
unsigned long long r=0;
size_t i;
if(!*size)
{
*(unsigned long long*)a=b;
*size=b>>32?2:1;
}
else if(b>>32)
{
unsigned long long c=(unsigned int)b;
b>>=32;
for(i=0;i<*size;++i)
{
unsigned int t[3]={0};
*(unsigned long long*)t=a[i]*c+(r&-1U);
*(unsigned long long*)(t+1)+=a[i]*b+(r>>32);
a[i]=t[0];
r=*(unsigned long long*)(t+1);
}
if(r)
{
*(unsigned long long*)(a+*size)=r;
*size+=r>>32?2:1;
}
}
else
{
for(i=0;i<*size;++i)
{
r+=a[i]*b;
a[i]=(unsigned int)r;
r>>=32;
}
if(r)
a[(*size)++]=(unsigned int)r;
}
assert(*size<LEN);
}
void rem(unsigned int *a,size_t *asz,const unsigned int*b,size_t bsz)
{
unsigned int r[LEN];
size_t rsz=0,l=*asz<<5,i;
while(l--)
{
if(!rsz)
{
if(a[l>>5]>>(l&31)&1)
r[rsz++]=1;
}
else
{
i=rsz-1;
if(r[rsz-1]>>31)
r[rsz++]=1;
while(i)
{
r[i]=r[i]<<1|r[i-1]>>31;
--i;
}
r[0]=(r[0]<<1)|((a[l>>5]>>(l&31))&1);
}
if(rsz>bsz)
{
for(i=bsz;i;--i)
*(unsigned long long*)(r+i-1)-=b[i-1];
while(rsz&&!r[rsz-1]) --rsz;
}
else if(rsz&&rsz==bsz)
{
for(i=rsz;i&&r[i-1]==b[i-1];--i);
if(!i||r[i-1]>b[i-1])
{
r[rsz-1]-=b[bsz-1];
for(i=rsz-1;i;--i)
*(unsigned long long*)(r+i-1)-=b[i-1];
while(rsz&&!r[rsz-1]) --rsz;
}
}
}
memcpy(a,r,sizeof r);
*asz=rsz;
assert(*asz<LEN);
}
unsigned long long exgcd(const unsigned int*a,size_t size,unsigned long long b)
{
long long x[2]={0,1};
unsigned long long aa=b,bb=0,r;
if(1==size)
bb=a[0]%b;
else
{
unsigned int tmp[LEN];
size_t tsz=size;
memcpy(tmp,a,sizeof tmp);
rem(tmp,&tsz,(unsigned int*)&b,b>>32?2:1);
assert(tsz<=2);
switch(tsz)
{
case 0:bb=0;break;
case 1:bb=*tmp;break;
case 2:bb=*(unsigned long long*)tmp;break;
}
}
do
{
long long t=x[0];x[0]=x[1];x[1]=t-aa/bb*x[0];
r=aa%bb;aa=bb;bb=r;
}while(bb);
if(x[0]>=0)
return (unsigned long long)x[0];
else
return (unsigned long long)((long long)b+x[0]);
}
附测试数据和结果
2 3 5 7 11 13 17 19
1 1 1 1 1 1 1 1
9699691
time:5.7e-05s
9223372036854775399 9223372036854775417 9223372036854775421 9223372036854775433 9223372036854775507 9223372036854775549 9223372036854775643 9223372036854775783
408 390 386 374 300 258 164 24
9223372036854775807
time:0.000285s
4294967111 4294967143 4294967161 4294967189 4294967197 4294967231 4294967279 4294967291
2147500667 2147495275 2147492692 2147489318 2147488498 2147485727 2147483783 2147483657
9223372036854775807
time:0.000137s
4294967111 4294967143 4294967161 4294967189 4294967197 4294967231 4294967279 4294967291
400879708 76365989 2309746472 1488927345 2481541213 2405183635 4065902492 1259857083
8690466096661279830
time:0.000127s
StartTime:=GetTickCount;
a1:=2; a2:=3; a3:=5; a4:=7; a5:=11; a6:=13; a7:=17; a8:=19;
b1:=1; b2:=1; b3:=1; b4:=1; b5:=1; b6:=1; b7:=1; b8:=1;
for i := 1 to a2 do
begin
n := (a1*i + b1) mod a2;
if n = b2 then
begin
c2 := a1*i + b1;
d2 := a1*a2;
break;
end;
end;
//i = 3 c2 = 7
for i := 1 to a3 do
begin
n := (d2*i + c2) mod a3;
if n = b3 then
begin
c3 := d2*i + c2;
d3 := d2*a3;
break;
end;
end;
//i = 4 c3 = 31
for i := 1 to a4 do
begin
n := (d3*i + c3) mod a4;
if n = b4 then
begin
c4 := d3*i + c3;
d4 := d3*a4;
break;
end;
end;
//i = 6 c4=211
for i := 1 to a5 do
begin
n := (d4*i + c4) mod a5;
if n = b5 then
begin
c5 := d4*i + c4;
d5 := d4*a5;
break;
end;
end;
//i = 10 c5=2311
for i := 1 to a6 do
begin
n := (d5*i + c5) mod a6;
if n = b6 then
begin
c6 := d5*i + c5;
d6 := d5*a6;
break;
end;
end;
//i = 12 c6=30031
for i := 1 to a7 do
begin
n := (d6*i + c6) mod a7;
if n = b7 then
begin
c7 := d6*i + c6;
d7 := d6*a7;
break;
end;
end;
//i = 16 c7=510511
for i := 1 to a8 do
begin
n := (d7*i + c7) mod a8;
if n = b8 then
begin
c8 := d7*i + c7;
d8 := d7*a8;
break;
end;
end;
//i = 18; c8=9699691
EndTime:=GetTickCount;
a1:=3; a2:=5; a3:=7; a4:=13; a5:=17; a6:=19; a7:=23; a8:=29;
b1:=1; b2:=2; b3:=4; b4:=6; b5:=2; b6:=10; b7:=1; b8:=11;
for i := 1 to a2 do
begin
n := (a1*i + b1) mod a2;
if n = b2 then
begin
c2 := a1*i + b1;
d2 := a1*a2;
break;
end;
end;
//i = 2 c2 = 7
for i := 1 to a3 do
begin
n := (d2*i + c2) mod a3;
if n = b3 then
begin
c3 := d2*i + c2;
d3 := d2*a3;
break;
end;
end;
//i = 4 c3 = 67
for i := 1 to a4 do
begin
n := (d3*i + c3) mod a4;
if n = b4 then
begin
c4 := d3*i + c3;
d4 := d3*a4;
break;
end;
end;
//i = 4 c4=487
for i := 1 to a5 do
begin
n := (d4*i + c4) mod a5;
if n = b5 then
begin
c5 := d4*i + c4;
d5 := d4*a5;
break;
end;
end;
//i = 5 c5=7312
for i := 1 to a6 do
begin
n := (d5*i + c5) mod a6;
if n = b6 then
begin
c6 := d5*i + c5;
d6 := d5*a6;
break;
end;
end;
//i = 18 c6=425002
for i := 1 to a7 do
begin
n := (d6*i + c6) mod a7;
if n = b7 then
begin
c7 := d6*i + c6;
d7 := d6*a7;
break;
end;
end;
//i = 2 c7=1306792
for i := 1 to a8 do
begin
n := (d7*i + c7) mod a8;
if n = b8 then
begin
c8 := d7*i + c7;
d8 := d7*a8;
break;
end;
end;
//i = 22; c8=224399662