This problem is mainly due to fill a third operation to maintenance intervals, rather than a point, otherwise T.
https://vjudge.net/problem/HDU-4893
Meaning of the questions: Enter n, q. N number expressed, which initializes the default number of n are zero, q has operations, the operation is divided into three types: 1, the input k, D, such that the position of the number k plus d. 2, the input l, r, find the interval [l, r] and the output. 3, an input l, r, the number in the interval [l, r] are changed number Feibolaqi, modifications such fabs [xF [i]] minimum, if there are a plurality of F [i] to meet the situation, with the minimum F [i]. ≤ ≤ n-100000. 1,. 1 ≤ m ≤ 100000, | D | <2 31 is
Method: For the first two operations can be used to update a single point of maintenance, but for the third operation if the update with a single point, then, will TLE (n ^ 2), so we have to update the interval, we need to know soon interval [l, r] interval and FIB, FIB simply maintain all of our numbers and update it in the build, and operate on a time line segment tree. Time complexity of n * log (n).
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 100050; int n, m; struct node { int l, r; LL sm1, sm2; bool t; } T[maxn << 2]; LL F[150]; void init() { F[0] = F[1] = 1; for(int i = 2; i <= 90; i++) F[i] = F[i - 1] + F[i - 2]; } LL FBI(LL x) { int pos = (int)(lower_bound(F, F + 80, x) - F); if(!pos) return F[0]; else { LL t1 = F[pos] - x; LL t2 = x - F[pos - 1]; if(t1 < t2) return F[pos]; else return F[pos - 1]; } } void pushup(int id) { T[id].sm1 = T[id << 1].sm1 + T[id << 1 | 1].sm1; T[id].sm2 = T[id << 1].sm2 + T[id << 1 | 1].sm2; } void pushdown(int id) { if(T[id].t) { T[id << 1].sm1 = T[id << 1].sm2; T[id << 1].t = 1; T[id << 1 | 1].sm1 = T[id << 1 | 1].sm2; T[id << 1 | 1].t = 1; T[id].t = 0; } } void build(int id, int l, int r) { T[id].l = l; T[id].r = r; T[id].t = 0; if(l == r) { T[id].sm1 = 0; T[id].sm2 = 1; return ; } else { int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); pushup(id); } } LL sum(int id, int l, int r) { if(T[id].l == l && T[id].r == r) return T[id].sm1; else { pushdown(id); int mid = (T[id].l + T[id].r) >> 1; if(r <= mid) return sum(id << 1, l, r); else if(l >= mid + 1) return sum(id << 1 | 1, l, r); else return sum(id << 1, l, mid) + sum(id << 1 | 1, mid + 1, r); } } void change(int id, int l, int r) { if(T[id].l == l && T[id].r == r) { T[id].sm1 = T[id].sm2; T[id].t = 1; return ; } else { pushdown(id); int mid = (T[id].l + T[id].r) >> 1; if(r <= mid) { change(id << 1, l, r); } else if(l >= mid + 1) { change(id << 1 | 1, l, r); } else { change(id << 1, l, mid); change(id << 1 | 1, mid + 1, r); } pushup(id); } } void update(int id, int pos, LL d) { if(T[id].l == T[id].r) { T[id].sm1 += d; T[id].sm2 = FBI(T[id].sm1); return ; } else { pushdown(id); int mid = (T[id].l + T[id].r) >> 1; if(pos <= mid) update(id << 1, pos, d); else update(id << 1 | 1, pos, d); pushup(id); } } int main() { init(); while(scanf("%d%d", &n, &m) != EOF) { build(1, 1, n);// LL d; int k, l, r, ty; for(int i = 1; i <= m; i++) { scanf("%d", &ty); if(ty == 1) { scanf("%d%lld", &k, &d); update(1, k, d); } else if(ty == 2) { scanf("%d%d", &l, &r); printf("%lld\n", sum(1, l, r)); } else { scanf("%d%d", &l, &r); change(1, l, r); } } } return 0; }