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