蓝桥杯 奖杯排序

题意:

给定一个序列 \(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
posted @ 2025-03-15 11:37  Guaninf  阅读(31)  评论(0)    收藏  举报