[CodeForces1110C]Meaningless Operations
Upd-2019/2/17:添加了特殊數據的求解方式。
題目鏈接:http://codeforces.com/problemset/problem/1110/C
題意簡述
定義函數\(f(a)\)為:
\[f(a)=\max\limits_{0<b<a} \{\gcd(a\oplus b,a~\& ~b)\}\]
給定\(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<k;b++)res=max(res,__gcd(k^b,k&b));return res; }然后華麗地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}^{+})\]
這樣,我們就完成了一般數據的計算公式推導啦。
特殊數據呢?
打表!!!
map<int,int>table;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<b<a} \{\gcd(a,b)\}\)即可。
而要求\(\gcd(a,b)\)的最大值,顯然只要\(b(b\ne a)\)是\(a\)的最大因子即可。
main code
#include<bits/stdc++.h> 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<<k)-1{register int b;for(b=2;(b*b<=a)&&(a%b);b++);//先求第二小的因子,再用a去除,即為最大因子。return __gcd(a,a/b);}return (1<<(log2(a)+1))-1; } signed main() {int Q;cin>>Q;for(int i=1;i<=Q;i++)cout<<Calc(read())<<endl;return 0; }轉載于:https://www.cnblogs.com/-Wallace-/p/10388639.html
總結
以上是生活随笔為你收集整理的[CodeForces1110C]Meaningless Operations的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 中 Behavior,
- 下一篇: [WC2018]通道