Codeforces 567C(思维)

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;

如果还是不理解可以手动模拟几组样例。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半碗无糖蓝莓冻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值