题目大概说给一个整数序列,问里面有几个包含三个数字的子序列ai,aj,ak,满足ai*k*k=aj*k=ak。
感觉很多种做法的样子,我想到这么一种:
- 枚举中间的aj,看它左边有多少个aj/k右边有多少个aj*k,两边个数的乘积就是答案的一部分贡献。
- 而左边各个数字的个数和右边各个数字可以用两个map维护,一边枚举一边删除或插入。
1 #include<cstdio> 2 #include<map> 3 #include<algorithm> 4 using namespace std; 5 int a[222222]; 6 int main(){ 7 map<long long,int> amap,bmap; 8 int n; 9 long long k; 10 scanf("%d%lld",&n,&k); 11 for(int i=0; i<n; ++i){ 12 scanf("%d",a+i); 13 ++bmap[a[i]]; 14 } 15 long long ans=0; 16 for(int i=0; i<n; ++i){ 17 --bmap[a[i]]; 18 if(a[i]%k==0){ 19 ans+=(long long)amap[a[i]/k]*bmap[a[i]*k]; 20 } 21 ++amap[a[i]]; 22 } 23 printf("%lld",ans); 24 return 0; 25 }