CF1634F Fibonacci Additions
Statement:
给出两个长度为
Solution:
先简化问题,令
其实这个问题可以直接上线段树解决。
但是我们考虑将区间操作转化为单点操作,有什么技巧可以实现呢? 差分!
差分的本质,其实是因为相邻项的增量有一定关系,根据关系设计出一个递推式,并且将区间转化为几个点的调整。
我们的增量
于是我们设计差分数组
分析操作带来的影响(这里分析
首先对于
Code:
#include<bits/stdc++.h> #define int long long using namespace std; const int N = 3e5 + 1145; int n, q, mod, a[N], b[N], c[N], d[N], f[N], cnt; void ch(int x, int ad){ if(x > n || x < 1) return; int tmp = (d[x] + (ad % mod + mod) % mod) % mod; if(d[x] == 0 && tmp) cnt--; else if(d[x] != 0 && (!tmp)) cnt++; d[x] = tmp; } signed main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> q >> mod; for(int i = 1; i <= n; i++) cin >> a[i]; for(int i = 1; i <= n; i++) cin >> b[i]; f[1] = f[2] = 1; for(int i = 3; i <= n + 114; i++) f[i] = (f[i - 1] + f[i - 2]) % mod; for(int i = 1; i <= n; i++) c[i] = (a[i] - b[i] + mod) % mod, d[i] = ((c[i] - c[i - 1] - c[max(0ll, i - 2)]) + mod) % mod, ch(i, 0), cnt += (d[i] == 0); while(q--){ char c; int l, r; cin >> c >> l >> r; if(c == 'A'){ ch(l, f[1]); ch(r + 1, -f[r - l + 2]); ch(r + 2, -f[r - l + 1]); } else{ ch(l, -f[1]); ch(r + 1, f[r - l + 2]); ch(r + 2, f[r - l + 1]); } if(cnt == n) cout << "YES" << "\n"; else cout << "No" << "\n"; } return 0; } /* c[i] = a[i] - b[i] d[i] = c[i] - c[i - 1] - c[i - 2] */
本文作者:Little_corn
本文链接:https://www.cnblogs.com/little-corn/p/18155062
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步