蜗蜗的数列(CF1634 F.Fibonacci Additions)-差分

代码源OJ #562. 蜗蜗的数列CF1634 F. Fibonacci Additions
参考

思路

题目要求验证数列 A,B 是否相同,我们构造数列 C, C i = A i − B i C_i=A_i-B_i Ci=AiBi ,检验数列 C 是否全为 0 即可;

对于一般的差分来说,连续区间加上定值,只需要在区间首末加上和减去这个值即可,但是此题加上的是斐波那契数列,我们需要特殊构造;

构造差分数组 D, D i = C i − C i − 1 − C i − 2 D_i=C_i-C_{i-1}-C_{i-2} Di=CiCi1Ci2 。我们可以发现如果对 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+Frl+2,Dr+2+Frl+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

卡常是坏文明

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值