代码源OJ #562. 蜗蜗的数列、CF1634 F. Fibonacci Additions;
参考;
思路
题目要求验证数列 A,B 是否相同,我们构造数列 C, C i = A i − B i C_i=A_i-B_i Ci=Ai−Bi ,检验数列 C 是否全为 0 即可;
对于一般的差分来说,连续区间加上定值,只需要在区间首末加上和减去这个值即可,但是此题加上的是斐波那契数列,我们需要特殊构造;
构造差分数组 D, D i = C i − C i − 1 − C i − 2 D_i=C_i-C_{i-1}-C_{i-2} Di=Ci−Ci−1−Ci−2 。我们可以发现如果对 C 的 [l,r] 区间进行操作,只需要对 D l + F 1 , D r + 1 + F r − l + 2 , D r + 2 + F r − l + 1 D_l+F_1,D_{r+1}+F_{r-l+2},D_{r+2}+F_{r-l+1} Dl+F1,Dr+1+Fr−l+2,Dr+2+Fr−l+1 ,其余项在这种构造方式下均被约去了;
更推广来说,对于类斐波那契数列,也可以通过类似的构造来降低时间复杂度
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// const ll M = 1e9 + 7;
#pragma GCC optimize(2)
int n, q;
ll m;
int tmp;
ll c[1000006];
ll d[1000006];
int f[1000006];
int upd(int x, int y)
{
int tmp = 0;
if (x >= 1 && x <= n)
{
tmp -= (d[x] != 0);
d[x] = (d[x] + y + m) % m;
tmp += (d[x] != 0);
}
return tmp;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n >> q >> m;
for (int i = 1; i <= n; i++)
{
cin >> c[i];
}
for (int i = 1; i <= n; i++)
{
cin >> tmp;
c[i] -= tmp;
}
int unz = 0;
d[1] = c[1];
d[2] = (c[2] - c[1] + m) % m;
for (int i = 3; i <= n; i++)
{
d[i] = (c[i] - c[i - 1] - c[i - 2] + 6 * m) % m;
}
for (int i = 1; i <= n; i++)
{
if (d[i])
unz++;
}
f[1] = 1 % m;
f[2] = 1 % m;
for (int i = 3; i <= n + 2; i++)
{
f[i] = (f[i - 1] + f[i - 2]) % m;
}
char g;
int l, r;
while (q--)
{
cin >> g >> l >> r;
if (g == 'A')
{
unz += upd(l, 1);
unz += upd(r + 1, -f[r - l + 2]);
unz += upd(r + 2, -f[r - l + 1]);
}
else
{
unz += upd(l, -1);
unz += upd(r + 1, f[r - l + 2]);
unz += upd(r + 2, f[r - l + 1]);
}
if (!unz)
cout << "Yes\n";
else
cout << "No\n";
}
return 0;
}
ED
卡常是坏文明