Such a question is sure to maintain the line tree, the focus is how to maintain the Fibonacci sequence so that can be quickly merged operations
Here's a very sexy operation:
maintenance of two values per interval:
1. f0∗al+f1∗al+1+ f 0∗a L + F 1∗a L + 1 + ... f_0*a_l+f_1*a_{l+1}+ ...
2. f1∗al+f2∗al+1+ F 1∗a L + F 2∗a L + 1 + ... f_1*a_l+f_2*a_{l+1}+ ...
we find that this sequence is transferred in the same way as the Fibonacci: As long as you add fi−1 F i−1 f_{i-1} and fi f i f_i, you can get the polynomial at the beginning of the next fi+1 f i + 1 f_{i+1}, that is, if each interval we put on The two expressions are written as a matrix, and each time a polynomial that begins with an arbitrary fi f I f_i can be obtained by multiplying several times of a transfer matrix
So when we consider the line tree merging two intervals, just multiply the right matrix by the "left length" of the transfer matrix, then add the two matrices together.
So we're done. Single-point modification and interval query
When we consider the interval plus operation, we will find that the interval +delta actually adds a prefix of the Fibonacci sequence to the interval and the Delta times, so the lazy tag can maintain
PS: Very Kathang, card often small tip: can not use a long long, even if you encounter multiplication and then temporarily to a long long, so that efficiency can almost increase by one times
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cstdlib > #include <utility> #include <cctype> #include <algorithm> #include <bitset> #include < set> #include <map> #include <vector> #include <queue> #include <deque> #include <stack > #include <cmath> #define LL Long long #define LB long double #define X First #define y second #define pair pair <int,int> #define PB push_back #define PF Push_front #define MP Make_pair #define LOWBIT (x) x & (x) using names
Pace std;
const int MOD=1E9;
Const LL LINF=2E16;
const int INF=2E9;
const int magic=348;
const double EPS=1E-10;
Const Double Pi=acos (-1);
inline int getint () {char ch;int res;bool f; while (!isdigit (Ch=getchar ()) && ch!= '-') {} if (ch== '-') f=false,res=0;
else f=true,res=ch-' 0 ';
while (IsDigit (Ch=getchar ())) res=res*10+ch-' 0 ';
return f?res:-res;
} int n,q; inline int MoD (LL x) {while (x>=mod) X-=mod;
return x;
} struct Matrix {int b[3][3];
inline void init () {b[1][1]=0;
B[1][2]=b[2][1]=b[2][2]=1;
} inline void Clear () {for (Register Int. i=1;i<=2;i++) for (register int j=1;j<=2;j++) b[i][j]=0;}
Inline Matrix operator + (const matrix MA) {matrix res;res.clear (); int i,j; for (i=1;i<=2;i++) for (j=1;j<=2;j++) Res.b[i][j]=mod (Res.b[i][j]+mod (B[i][j]+ma.b[i][j]
));
return res;
} Inline Matrix operator * (const matrix MA) {matrix res;res.clear (); int i,j,k; for (i=1;i<=2;i++) for (j=1;j<=2;j++) for (k=1;k<=2;k++) Res.b[i]
[J]=mod (res.b[i][j]+ (Long Long) b[i][k]*ma.b[k][j])%mod);
return res;
} Inline Matrix operator ^ (const matrix MA) {matrix res;res.b[1][1]=res.b[1][2]=0;int j,k;
for (j=1;j<=2;j++)for (k=1;k<=2;k++) Res.b[1][j]=mod (res.b[1][j]+ ((Long Long) b[1][k]*ma.b[k][j])%mod);
return res;
} Inline Matrix operator & (const matrix MA) {matrix res;res.b[1][1]=res.b[1][2]=0;int J;
for (j=1;j<=2;j++) Res.b[1][j]=mod (Res.b[1][j]+mod (b[1][j]+ma.b[1][j));
return res; }//Here the & and ^ and the above + and * are the same, just for the card constant wrote a matrix//only the upper line of the card version, after all, my code is pressure-coded ...}
TRANS,MA[200048];
LL fib[200048],sum1[200048],sum2[200048];
int a[200048];
namespace Segmenttree {struct node {int left,right,len,lazy;
Matrix Ma;
}TREE[1000048];
Inline matrix pushup (matrix X,matrix y,int starter) {if (starter) y=y^ma[starter];x=x&y;
return x;
} inline void pushdown (int cur) {tree[cur<<1].lazy=mod (tree[cur<<1].lazy+tree[cur].lazy); tree[cur<<1|1</