蓝桥杯 奖杯排序

题意:
给定一个序列 \(a\) , 公差 \(k\) , 求可形成长度大于2的等差数列数量
思路:
枚举每个元素作为右端点时形成的等差数列数量 , 动态规划 , 使用 \(mp\) 存储之前的某个值为右端点所能求得的等差数列数量
当枚举到 \(a_i\) 时 , 此时它上一个元素为 \(a_i-k\) , 那么用mp可以获得到以 \(a_i-k\) 结尾的数列个数 , 而其中任何一种都可以在后面接上一个 \(a_i\)
除此之外 , 还有新的链产生: $a_i-k $ 到 $ a_i$ 链 , 所以还应当统计出 \(a_i-k\) 在之前的出现次数
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long int
int read()
{
int s= 0 ,f = 1;
char ch = getchar();
while(ch>'9' || ch < '0')
{
if(ch == '-')
f = -1;
ch = getchar();}
while(ch >='0' && ch <='9')
{
s = s *10 + ch-'0';
ch = getchar();
}
return f *s;
}
const int N = 2e5+10;
int a[N];
const int p= 1e9+7;
signed main()
{
int n,k;
n =read(), k =read();
for(int i = 1; i<= n; i++)
{
a[i] =read();
}
unordered_map<int,int>mp;
unordered_map<int,int>sz;
int ans = 0;
for (int i = 1; i<= n; i++) {
ans = (ans + mp[a[i]-k] + sz[a[i]-k] )% p;
mp[a[i]] += mp[a[i]-k] +sz[a[i]-k];
mp[a[i]] %= p;
sz[a[i]]++;
sz[a[i]] %= p;
}
cout<<ans;
return 0;
}
//5 2
//1 2 4 21 4

浙公网安备 33010602011771号