Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4893
Question: The range of 0.1 million is initially 0, 10 thousand operations. The three operations are single-point modifications, and each number is changed to the nearest Fibonacci number and the sum of the intervals.
Analysis: Use a flag to record whether the segment is changed to the Fibonacci number. At the same time, maintain a sum1 to indicate the number of the segments and the sum of the intervals if the segment is changed to the Fibonacci number. Sum1 is the interval length, and is updated after a single point is modified. it overwrites sum when needed.
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 struct T{ 7 long long sum, sum1; 8 bool flag; 9 }t[100100 << 2]; 10 int n, m; 11 int c, x, y; 12 long long f[100]; 13 void pushup(int x) 14 { 15 int ls = x << 1, rs = x << 1 | 1; 16 t[x].sum = t[ls].sum + t[rs].sum; 17 t[x].sum1 = t[ls].sum1 + t[rs].sum1; 18 } 19 void pushdown(int x) 20 { 21 if (t[x].flag){ 22 t[x<<1].sum = t[x<<1].sum1; 23 t[x<<1].flag = true; 24 t[x<<1|1].sum = t[x<<1|1].sum1; 25 t[x<<1|1].flag = true; 26 t[x].flag = false; 27 } 28 } 29 void build(int x, int l, int r) 30 { 31 t[x].flag = false; 32 if (l == r){ 33 t[x].flag = t[x].sum = 0; 34 t[x].sum1 = 1; 35 return; 36 } 37 int mid = l + r >> 1; 38 build(x<<1, l, mid); 39 build(x<<1|1, mid+1, r); 40 pushup(x); 41 } 42 void add(int x, int l, int r, int p, long long val) 43 { 44 if (l == r){ 45 t[x].sum += val; 46 if (t[x].sum >= f[91]) 47 t[x].sum1 = f[91]; 48 else if (t[x].sum <= 1) 49 t[x].sum1 = 1; 50 else{ 51 long long * p = upper_bound(f, f+92, t[x].sum); 52 if (t[x].sum - *(p-1) <= *p - t[x].sum) 53 t[x].sum1 = *(p-1); 54 else 55 t[x].sum1 = *p; 56 } 57 return; 58 } 59 int mid = l + r >> 1; 60 pushdown(x); 61 if (p <= mid) 62 add(x<<1, l, mid, p, val); 63 if (p > mid) 64 add(x<<1|1, mid+1, r, p, val); 65 pushup(x); 66 } 67 void tra(int x, int l, int r, int s, int e) 68 { 69 if (l == r){ 70 t[x].sum = t[x].sum1; 71 return; 72 } 73 if (s <= l && r <= e){ 74 t[x].flag = true; 75 t[x].sum = t[x].sum1; 76 return; 77 } 78 int mid = l + r >> 1; 79 pushdown(x); 80 if (s <= mid) 81 tra(x<<1, l, mid, s, e); 82 if (mid < e) 83 tra(x<<1|1, mid+1, r, s, e); 84 pushup(x); 85 } 86 long long query(int x, int l, int r, int s, int e) 87 { 88 if (l == r) 89 return t[x].sum; 90 if (s <= l && r <= e) 91 return t[x].sum; 92 long long tmp = 0; 93 int mid = l + r >> 1; 94 pushdown(x); 95 if (s <= mid) 96 tmp += query(x<<1, l, mid, s, e); 97 if (mid < e) 98 tmp += query(x<<1|1, mid+1, r, s, e); 99 pushup(x);100 return tmp;101 }102 int main()103 {104 f[0] = 1; f[1] = 1;105 for (int i = 2; i <= 91; i++)106 f[i] = f[i-1] + f[i-2];107 while(scanf("%d %d", &n, &m) != EOF)108 {109 build(1, 1, n);110 while(m--){111 scanf("%d %d %d", &c, &x, &y);112 if (c == 1) add(1, 1, n, x, (long long)y);113 if (c == 2) printf("%I64d\n", query(1, 1, n, x, y));114 if (c == 3) tra(1, 1, n, x, y);115 }116 }117 return 0;118 }