思路讲解
赛时最后30min过了,通过网上搜到的结论,
gcd(a,b)=a xor b=a−b(结论,下面是推理过程)
a−b<=a xor b=gcd(a,b)
gcd(a,b)∗x=a, gcd(a,b)∗y=b可得a−b=(x−y)∗gcd(a,b)可得a−b<=gcd(a,b)又因为a−b>=gcd(a,b)gcd(a,b)=a−b
当然不可能每题都用结论嘛,所以看看枚举可不可以过
搞半天发现和我的赛时代码也差不多,jiangly差不多也是我这个做法
最重要的其实就是更换枚举尺度,枚举a太慢了,可以枚举g,进而枚举a时只用枚举g的倍数就行了
AC代码
AC
https://ac.nowcoder.com/acm/contest/view-submission?submissionId=74967799
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pll; typedef array<ll,3> arr; const ll MAXN=static_cast<ll>(2e5)+10; ll N,A[MAXN]; ll Cnt[MAXN]; ll gcd(ll a,ll b) { if(b==0) return a; return gcd(b,a%b); }
int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin>>N; for(int i=1;i<=N;++i) { cin>>A[i]; Cnt[A[i]]+=1; } ll ans=0;ll m=*max_element(&A[1],&A[N+1]); for(int g=1;g<=m;++g) { for(int a=g;a<=m;a+=g) { ll b=a^g; if(a<b && gcd(a,b)==g && b<=m) { ans+=Cnt[a]*Cnt[b]; } } } cout<<ans<<endl; return 0; }
|
赛时AC记录
https://ac.nowcoder.com/acm/contest/view-submission?submissionId=74946535
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pll; typedef array<ll,3> arr; const ll MAXN=static_cast<ll>(2e5)+10; ll N,T,A[MAXN]; ll gcd(ll a,ll b) { if(b==0) return a; return gcd(b,a%b); } inline ll lowbit(ll x) { return x&(-x); }
int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin>>N; for(int i=1;i<=N;++i) { cin>>A[i]; } sort(&A[1],&A[N+1]); ll ans=0; for(int i=1;i<=A[N];++i) { for(int j=i;j<=A[N]-i;j+=i) { if((j^(j+i))!=i) continue; ans+=(upper_bound(&A[1],&A[N+1],j)-&A[0]-(lower_bound(&A[1],&A[N+1],j)-&A[0])) * (upper_bound(&A[1],&A[N+1],j+i)-&A[0]-(lower_bound(&A[1],&A[N+1],j+i)-&A[0])); } } cout<<ans<<endl; return 0; }
|
心路历程(WA,TLE,MLE……)