Upd-2019/2/17:添加了特殊数据的求解方式。
题目链接:http://codeforces.com/problemset/problem/1110/C
题意简述
定义函数\(f(a)\)为:
\[f(a)=\max\limits_{0
给定\(a_1,a_2,...,a_q\)对于\(q\)个询问,求出\(f(a_1),f(a_2),...,f(a_q)\)。
题解
先放一个暴力代码:
int f(int a)
{
int res=-1;
for(int b=1;b
然后华丽地TLE。
这种题一般都是找规律的,我们先打个表:
f( 2)= 3;
f( 3)= 1;
f( 4)= 7;
f( 5)= 7;
f( 6)= 7;
f( 7)= 1;
f( 8)= 15;
f( 9)= 15;
f( 10)= 15;
f( 11)= 15;
f( 12)= 15;
f( 13)= 15;
f( 14)= 15;
f( 15)= 5;
f( 16)= 31;
f( 17)= 31;
f( 18)= 31;
f( 19)= 31;
f( 20)= 31;
f( 21)= 31;
f( 22)= 31;
f( 23)= 31;
f( 24)= 31;
f( 25)= 31;
f( 26)= 31;
f( 27)= 31;
f( 28)= 31;
f( 29)= 31;
f( 30)= 31;
f( 31)= 1;
f( 32)= 63;
f( 33)= 63;
f( 34)= 63;
f( 35)= 63;
f( 36)= 63;
f( 37)= 63;
f( 38)= 63;
f( 39)= 63;
f( 40)= 63;
...... ......
我们惊喜的发现:除了\(f(2^{k}-1)\)是毫无规律的之外,其他的好像都于\(2^k-1\)有关。
先推出一个简略的公式:
\[f(n)=2^{k+1}-1(2^k<=n<2^{k+1}-1)\]
稍微普遍化一下,即为:
\[f(n)=2^{\left\lfloor log_2n \right\rfloor+1}-1 (n\ne 2^{t+1}-1,0\le t\le2^{24},t\in \mathbb{Z}^{+})\]
这样,我们就完成了一般数据的计算公式推导啦。
特殊数据呢?
打表!!!
maptable;
table[1]=-1;
table[3]=1;
table[7]=1;
table[15]=5;
table[31]=1;
table[63]=21;
table[127]=1;
table[255]=85;
table[511]=73;
table[1023]=341;
table[2047]=89;
table[4095]=1365;
table[8191]=1;
table[16383]=5461;
table[32767]=4681;
table[65535]=21845;
table[131071]=1;
table[262143]=87381;
table[524287]=1;
table[1048575]=349525;
table[2097151]=299593;
table[4194303]=1398101;
table[8388607]=178481;
table[16777215]=5592405;
table[33554431]=1082401;
后来才发现:
\(f(2^{k}-1)\)也是可以求的!!!
当\(a=2^{k}-1\)时:
\[a\& b=b,a\oplus b=a-b\]
\(a=(111...11)_{(2)}\)
\[\therefore \gcd(a\oplus b,a~\& ~b)=\gcd(a-b,b)\]
根据更相损减术,可得:
\[\gcd(a-b,b)=\gcd(a,b)\]
现在只要求\(\max\limits_{0即可。
而要求\(\gcd(a,b)\)的最大值,显然只要\(b(b\ne a)\)是\(a\)的最大因子即可。
main code
#include
using namespace std;
inline int read(){int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return f*x;}
inline int log2(int a){return floor(log(a)/log(2));}
inline int Calc(int a)
{
if(log2(a)!=log2(a+1))//判断a是否为(1<>Q;
for(int i=1;i<=Q;i++)
cout<