C - Geometric Progression
传送门.
很有趣的一道题目,刚开始写的深搜,TLE了,后来看了大佬的代码,发现思路很有意思。
题目
Polycarp loves geometric progressions very much. Since he was only three years old, he loves only the progressions of length three. He also has a favorite integer k and a sequence a, consisting of n integers.
He wants to know how many subsequences of length three can be selected from a, so that they form a geometric progression with common ratio k.
A subsequence of length three is a combination of three such indexes i1, i2, i3, that 1 ≤ i1 < i2 < i3 ≤ n. That is, a subsequence of length three are such groups of three elements that are not necessarily consecutive in the sequence, but their indexes are strictly increasing.
A geometric progression with common ratio k is a sequence of numbers of the form b·k0, b·k1, …, b·k~r - 1~.
Polycarp is only three years old, so he can not calculate this number himself. Help him to do it.
Input
The first line of the input contains two integers, n and k (1 ≤ n, k ≤ 2·105), showing how many numbers Polycarp’s sequence has and his favorite number.
The second line contains n integers a1, a2, …, an ( - 109 ≤ ai ≤ 109) — elements of the sequence.
Output
Output a single number — the number of ways to choose a subsequence of length three, such that it forms a geometric progression with a common ratio k.
样例
inputCopy
5 2
1 1 2 2 4
outputCopy
4
inputCopy
3 1
1 1 1
outputCopy
1
inputCopy
10 3
1 2 6 2 3 6 9 18 3 9
outputCopy
6
题目大意
找3个公比是k的数构成一个等比数列,问一共能找到多少个,等比数列中下标的大小必须按照数列中下标的大小排列
思路
用两个map分别记录每个数的次数以及预计可以组成等比数列的组数,这样等最后一个符合条件的数构成等比数列后直接总数加起来。
#include <iostream>
#include <map>
#include <algorithm>
#include <string>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;
int n,k;
ll cnt;
map<int,ll>mp1,mp2;//选择用mp1记录次数,mp2记录组数
int main()
{
cin >> n >> k;
for(int i = 0;i < n;i ++)
{
ll x;
cin >> x;
if(x % k == 0)
{
ll t1 = mp2[x / k];
cnt += t1;
ll t2 = mp1[x / k];
mp2[x] += t2;
}
mp1[x] ++;
}
cout << cnt << endl;
return 0;
}
手动模拟一下样例1
1 1的时候mp1[1] ++;
第一个2出现的时候mp2[2] = 2,这时说明2可以和前边的1预组成两个等比数列;
第二个2出现,更新mp2[2],mp2[2] = 4,说明2 和 1 可以预组成4个等比数列;
4出现后得到组数4;
如果还是不理解可以手动模拟几组样例。