Codeforces 718C solution
Posted jhseng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 718C solution相关的知识,希望对你有一定的参考价值。
Description
Sasha has an array of integers a1, a2, ..., an. You have to perform m queries. There might be queries of two types:
- 1 l r x — increase all integers on the segment from l to r by values x;
- 2 l r — find , where f(x) is the x-th Fibonacci number. As this number may be large, you only have to find it modulo 109 + 7.
In this problem we define Fibonacci numbers as follows: f(1) = 1, f(2) = 1, f(x) = f(x - 1) + f(x - 2) for all x > 2.
Sasha is a very talented boy and he managed to perform all queries in five seconds. Will you be able to write the program that performs as well as Sasha?
The first line of the input contains two integers n and m (1 ≤ n ≤ 100 000, 1 ≤ m ≤ 100 000) — the number of elements in the array and the number of queries respectively.
The next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109).
Then follow m lines with queries descriptions. Each of them contains integers tpi, li, ri and may be xi (1 ≤ tpi ≤ 2, 1 ≤ li ≤ ri ≤ n, 1 ≤ xi ≤ 109). Here tpi = 1 corresponds to the queries of the first type and tpi corresponds to the queries of the second type.
It‘s guaranteed that the input will contains at least one query of the second type.
For each query of the second type print the answer modulo 109 + 7.
5 4
1 1 2 1 1
2 1 5
1 2 4 2
2 2 4
2 1 5
5
7
9
Initially, array a is equal to 1, 1, 2, 1, 1.
The answer for the first query of the second type is f(1) + f(1) + f(2) + f(1) + f(1) = 1 + 1 + 1 + 1 + 1 = 5.
After the query 1 2 4 2 array a is equal to 1, 3, 4, 3, 1.
The answer for the second query of the second type is f(3) + f(4) + f(3) = 2 + 3 + 2 = 7.
The answer for the third query of the second type is f(1) + f(3) + f(4) + f(3) + f(1) = 1 + 2 + 3 + 2 + 1 = 9.
没什么可说的,就是线段树维护fib递推矩阵,线段树不难写,难写的是矩阵部分,细节很多。要是封装性太强容易把代码写得很java。
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define sot(a,b) sort(a+1,a+1+b) 28 #define rep1(i,a,b) for(int i=a;i<=b;++i) 29 #define rep0(i,a,b) for(int i=a;i<b;++i) 30 #define repa(i,a) for(auto &i:a) 31 #define eps 1e-8 32 #define int_inf 0x3f3f3f3f 33 #define ll_inf 0x7f7f7f7f7f7f7f7f 34 #define lson curPos<<1 35 #define rson curPos<<1|1 36 /* namespace */ 37 using namespace std; 38 /* header end */ 39 40 const int maxn = 1e5 + 10; 41 const int mod = 1e9 + 7; 42 43 struct Matrix 44 { 45 ll data[2][2]; 46 Matrix() 47 { 48 data[0][0] = data[0][1] = data[1][0] = data[1][1] = 0; 49 } 50 //变为转移矩阵 51 inline void tran() 52 { 53 data[0][1] = data[1][0] = data[1][1] = 1, data[0][0] = 0; 54 } 55 //初始化为对角矩阵 56 inline void init() 57 { 58 *this = Matrix(); 59 rep1(i, 0, 1) data[i][i] = 1; 60 } 61 //返回矩阵第x行 62 inline ll *operator[](int x) 63 { 64 return data[x]; 65 } 66 //定义矩阵乘法 67 inline void operator*=(Matrix &rhs) 68 { 69 Matrix qAns; 70 rep1(k, 0, 1) 71 { 72 rep1(i, 0, 1) 73 { 74 rep1(j, 0, 1) 75 qAns[j][i] = (qAns[j][i] + data[j][k] * rhs[k][i]) % mod; 76 } 77 } 78 *this = qAns; 79 } 80 //矩阵快速幂 81 inline void operator^=(int x) 82 { 83 Matrix base = *this, qAns; 84 rep1(i, 0, 1) qAns[i][i] = 1; 85 for (register int i = x; i; i >>= 1, base *= base) 86 if (i & 1) qAns *= base; 87 *this = qAns; 88 } 89 inline void operator+=(Matrix &rhs) 90 { 91 rep1(i, 0, 1) 92 { 93 rep1(j, 0, 1) 94 { 95 data[i][j] = (data[i][j] + rhs[i][j]) % mod; 96 } 97 } 98 } 99 //输出 100 inline void pr() 101 { 102 rep1(t, 0, 1) 103 { 104 rep1(i, 0, 1) printf("%d ", data[t][i]); 105 puts(""); 106 } 107 } 108 } seg[maxn << 2], add[maxn << 2]; 109 110 int n, m; 111 Matrix qAns, markdown; 112 bool lazyTag[maxn << 2]; 113 114 inline void pushdown(int curPos) 115 { 116 if (!lazyTag[curPos]) return; 117 seg[lson] *= add[curPos]; seg[rson] *= add[curPos]; 118 add[lson] *= add[curPos]; add[rson] *= add[curPos]; 119 lazyTag[lson] = lazyTag[rson] = 1; 120 add[curPos].init(); lazyTag[curPos] = 0; 121 } 122 123 void build(int curPos, int curL, int curR) 124 { 125 if (curL == curR) 126 { 127 seg[curPos].tran(); 128 add[curPos].init(); 129 int tmp; scanf("%d", &tmp); 130 seg[curPos] ^= tmp - 1; 131 return; 132 } 133 int mid = (curL + curR) >> 1; 134 add[curPos].init(); 135 build(lson, curL, mid); build(rson, mid + 1, curR); 136 seg[curPos] = Matrix(); 137 seg[curPos] += seg[lson]; seg[curPos] += seg[rson]; 138 } 139 140 void update(int curPos, int curL, int curR, int qL, int qR) 141 { 142 if (qL <= curL && curR <= qR) 143 { 144 add[curPos] *= markdown; seg[curPos] *= markdown; lazyTag[curPos] = 1; 145 return; 146 } 147 int mid = (curL + curR) >> 1; 148 pushdown(curPos); 149 if (qL <= mid) update(lson, curL, mid, qL, qR); 150 if (mid < qR) update(rson, mid + 1, curR, qL, qR); 151 seg[curPos] = Matrix(); 152 seg[curPos] += seg[lson]; seg[curPos] += seg[rson]; 153 } 154 155 void query(int curPos, int curL, int curR, int qL, int qR) 156 { 157 if (qL <= curL && curR <= qR) 158 { 159 qAns += seg[curPos]; 160 return; 161 } 162 int mid = (curL + curR) >> 1; 163 pushdown(curPos); 164 if (qL <= mid) query(lson, curL, mid, qL, qR); 165 if (mid < qR) query(rson, mid + 1, curR, qL, qR); 166 seg[curPos] = Matrix(); 167 seg[curPos] += seg[lson]; seg[curPos] += seg[rson]; 168 } 169 170 int main() 171 { 172 scanf("%d%d", &n, &m); 173 build(1, 1, n); 174 rep1(cnt, 1, m) 175 { 176 int op; scanf("%d", &op); 177 if (op == 1) 178 { 179 int x, y, t; scanf("%d%d%d", &x, &y, &t); 180 markdown.tran(); markdown ^= t; 181 update(1, 1, n, x, y); 182 } 183 else 184 { 185 int x, y; scanf("%d%d", &x, &y); 186 qAns = Matrix(); 187 query(1, 1, n, x, y); 188 printf("%lld\n", (qAns[0][0] + qAns[0][1]) % mod); 189 } 190 } 191 return 0; 192 }
以上是关于Codeforces 718C solution的主要内容,如果未能解决你的问题,请参考以下文章
codeforces CF718C Sasha and Array 线段树维护矩阵