题意:要求计算出一个长为n的序列中,长度为3的子序列且这个子序列能构成公比为k的等比数列的总个数。
假设某一个等比以p结尾,那么他的贡献,就来自于,p/k,p/k/k,那么如何同届呢。我们可以发现,以p结尾的子序列,贡献和为,在第一个p/k前面有多少个p/k/k,第二个p/k前面有多少个p/k/k,。。。。。以此类推。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
char ch = getchar(); int x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int n, k;
const int N = 2e5 + 10;
ll a[N];
map<ll, ll>mp,cnt;
int main() {
n = read(), k = read();
up(i, 0, n)a[i] = read();
if (k == 1)
{
ll ans = 0;
up(i, 0, n)mp[a[i]]++;
up(i, 0, n)if (mp[a[i]] > 2)ans += mp[a[i]] * 1ll * (mp[a[i]] - 1)*(mp[a[i]] - 2) / 6,mp[a[i]]=0;
cout << ans << endl;
return 0;
}
ll ans = 0;
int zero = 0;
up(i, 0, n)
{
cnt[a[i]]++;
if (a[i] % k == 0 && a[i] != 0)
{
mp[a[i] * k] += cnt[a[i] / k];
}
else if (a[i] == 0)zero++;
ans += mp[a[i]];
}
cout << ans + (zero) * 1ll * (zero - 1)*(zero - 2) / 6 << endl;
}