SRM567 DIV2 -Level2

<問題>
①2つの整数NとMが与えられる。
②1<=A<=N、1<=B<=Mである、(sqrt(A)+sqrt(B))^2が整数であるXが存在するとき、AとBの組み合わせの数を返す。

<解き方>
Aが1のとき、B=1,4,9,16・・・
Aが2のとき、B=2*1、2*9、2*16・・・であることがわかります。
そのため、Aを1からNまでループさせ、
BをA*1^2、A*2^2・・・と繰り返して数を足してあげて
最後にその和をかえしてあげればよいです。
O(80000*900=72000000=7*10^7)なので微妙。

もう少し計算量を削減するには、
Aが2で選ばれるBの数と、
Aが2*2^2、2*3^2・・・で選ばれるBの数は一緒であることが分かります。
そこでAもまとめて計算することで計算量が削減できます。
おおまかですがO(900*900=810000=8*10^5)ぐらい。

<コード>
class TheSquareRootDilemma {

public: int countPairs(int N, int M) {
vector<int> check(77778,0);
int ans=0;

FORE(i,1,M+1){
if(check[i]==1)continue;
int x=0;
for(int j=1;j*j*i<=M;j++){
if(check[i*j*j]==1)continue;
check[i*j*j]=1;
x++;
}
int y=0;
for(int j=1;j*j*i<=N;j++)y++;
ans+=(x*y);
}
return ans;
}

};

このエントリーをはてなブックマークに追加