cf1634 F. Fibonacci Additions
题意:
给定两个一样长的数组 \(a,b\) 和一个模数 \(M\)。每次操作选定一个数组的一个区间,将区间中的数对位加上斐波那契数列(1,1,2,3,...)
每次操作后,判断两个数组是否在模 \(M\) 意义下是否相同。
\(n,q\le 3e5,0\le a_i,b_i\le M\)
思路:
俩数组对应位置作差,记录非零的数量,全为0就是相等。
考虑差分数组 \(d_i=a_{i}-a_{i-1}-a_{i-2}\),每次操作 \([l,r]\) 只需改变三个位置:\(d_l,d_{r+1},d_{r+2}\)
ll n, q, mod, a[N], b[N], fib[N], sum;
void add(int x, int y) {
sum -= (a[x] != 0);
a[x] += y, a[x] %= mod;
if(a[x] < 0) a[x] += mod;
sum += (a[x] != 0);
}
signed main() {
iofast;
cin >> n >> q >> mod;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1, x; i <= n; i++) {
cin >> x, a[i] -= x;
a[i] %= mod; if(a[i] < 0) a[i] += mod;
}
//变成差分数组
for(int i = n; i >= 2; i--) {
a[i] -= a[i-1] + a[i-2];
a[i] %= mod; if(a[i] < 0) a[i] += mod;
if(a[i]) sum++; //非零的个数
}
if(a[1]) sum++;
//预处理斐波那契数列
fib[1] = 1; for(int i = 2; i < N; i++)
fib[i] = (fib[i-1] + fib[i-2]) % mod;
while(q--) {
char c; int t, l, r; cin >> c >> l >> r;
t = (c == 'A' ? 1 : -1);
add(l, t);
if(r + 1 <= n) add(r+1, -t * fib[r-l+2]);
if(r + 2 <= n) add(r+2, -t * fib[r-l+1]);
cout << (!sum ? "YES" : "NO") << endl;
}
}