牛客周赛49 F 嘤嘤不想找最小喵

牛客周赛49 F 嘤嘤不想找最小喵

解题思路:

\(a_i +a_{i +2 k} = 2 a_{i + k}\)

\(a_{i + 2k} - a_i = 2d, 则a_{i + k} = a_i + d\)

所以,对于\(a_i ,..., a_{n - 2k}\),有\(a_{i +k},...,a_{n - k}\)为他们等差数列的下一项。

同理,对于\(a_i ,..., a_{n - 2k}\),有\(a_{i + 2k},...,a_{n}\)为他们等差数列的往后第二项。

整个数列可以分成三段,存在关系\([a_i, ... a_{n - 2k}] + [a_{i + 2k}, ... a_{n}] = 2\times[a_{i + k},...,a_{n - k}]\),其中每一项一一对应。

我们可以将每一项看成是高进制的每一个数位,这样就可以用哈希进行判断了。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i128 = __int128_t;
using ull = unsigned long long;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
#define fi first
#define se second
const int N = 1e6 + 10;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int l, int r) { return rng() % (r - l + 1) + l; }
const ll P = 13331;
ull h[N];
ull p[N];

void solve()
{
    int n;
    cin >> n;
    vector<ll> a(n + 1);
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    p[0] = 1;
    for (int i = 1; i <= n; i++)
    {
        h[i] = (h[i - 1] * P + a[i]);
        p[i] = p[i - 1] * P;
    }
    auto get = [&](int l, int r)
    {
        return h[r] - h[l - 1] * p[r - l + 1];
    };
    for (int i = 1; i <= n; i++)
    {
        if (get(1, n - 2 * i) + get(2 * i + 1, n) == 2 * get(i + 1, n - i))
        {
            cout << i << '\n';
            return;
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}
posted @ 2024-07-01 15:58  value0  阅读(46)  评论(0)    收藏  举报