链接:https://codeforces.com/contest/1831/problem/D
脑子确实不好使,没啥思路,看jls代码之后豁然开朗。
思路:先枚举约数s,因为\(b_i+b_j\)不会超过4e5,所以第一层枚举所有约数为根号级别,第二层循环里枚举所有对数,统计\(v = a_i*s-b_i\)的所有个数,只有当\(a_i\)的值与s的值相等时,才能去更新cnt[v]的值。
注意点:本题必须从小到大按\(a_i\)排序,因为我们枚举的s为根号级别,只能用小的约数去找大的约数,不能反过来。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
pair<int,int> num[N];
int cnt[N];
void solve(){
int n;
cin>>n;
for (int i=1;i<=n;i++) cin>>num[i].first;
for (int i=1;i<=n;i++) cin>>num[i].second;
sort(num+1,num+1+n);
long long ans = 0;
for (int s = 1 ; s*s <= 2*n ; s++){
for (int i=1;i<=n;i++) cnt[i] = 0;
for (int i=1;i<=n;i++){
int v = s*num[i].first-num[i].second;
if (v>=1&&v<=n) ans += cnt[v];
if (num[i].first==s) cnt[num[i].second]++;
}
}
cout<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T;
T = 1;
cin>>T;
while(T--) solve();
return 0;
}
标签:约数,int,cf,875d,枚举,num,div.2,根号
From: https://www.cnblogs.com/xjwrr/p/17441335.html