题解:P11701 [ROIR 2025] 平方差
题解:P11701 [ROIR 2025] 平方差
赛时被创飞了,所以应当好好想一下这样的题该怎么做。
题目思路
朴素算法
按题意模拟即可。但是显然会炸。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll l,r,d,cnt=0;
int main(){
cin>>d>>l>>r;
for(int i=l;i<=sqrt(r);i++){
for(int j=i;j<=sqrt(r);j++){
if((j+i)*(j-i)==d) cnt++;
}
}
cout<<cnt;
return 0;
}
时间复杂度 \(O(n^{2})\)。
优化
平方差公式:\((a+b)(a-b)=a^2-b^2\)。
由题可得 \(x^2-y^2=d\) 可以变成 \((x-y)(x+y)=d\)。
令 \(a=x-y\),\(b=x+y=\frac{d}{a}\),则一定满足 \(a < b\) 且 \(a \cdot b = d\)。所以枚举 \(a\) 即可。枚举范围 \(\left[1,\sqrt{d}\right)\)。
又可得 \(x=\frac{a+b}{2}\),\(y=\frac{b-a}{2}\),判断是否满足 \(l \le y^2 < x^2 \le r\) 即可。
注意为了使 \(x\) 和 \(y\) 为整数,\(a\) 和 \(b\) 的奇偶性必须相同。
时间复杂度 \(O(\sqrt{d})\)。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll d,l,r,cnt;
int main() {
cin>>d>>l>>r;
for (ll a=1;a<sqrt(d);a++) {
if(d%a!=0) continue;
ll b=d/a;
if((a%2)!=(b%2)) continue;
ll x=(a+b)/2;
ll y=(b-a)/2;
if(y*y>=l&&x*x<=r&&y*y<x*x) cnt++;
}
cout<<cnt;
return 0;
}