牛客周賽49 F 嚶嚶不想找最小喵

value0發表於2024-07-01

牛客周賽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;
}