题意:给你一个序列,其中有三种操作
1)位置为K 的数+ D
2)求 l-r 区间和
3)把 l-r 区间里面的所有数都变为理它最近的斐波纳契数
解题思路:这个题的区间更新其实可以在单点更新的时候就得出,为节点维护两个 和,一个是 斐波纳契和 一个是正常和 ,再看这个区间有没有被3覆盖,特判一下就行了。
解题代码:
1 // File Name: 1007.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月29日 星期二 12时49分33秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 using namespace std; 26 #define maxn 100005 27 struct node{ 28 int is3 ; 29 int m , r , l ; 30 LL sum ,fsum ; 31 }tree[maxn << 2]; 32 LL f[100]; 33 int L(int x) 34 { 35 return 2* x; 36 } 37 int R(int x) 38 { 39 return 2*x + 1; 40 } 41 void pushup(int c) 42 { 43 tree[c].sum = tree[L(c)].sum + tree[R(c)].sum ; 44 tree[c].fsum = tree[L(c)].fsum + tree[R(c)].fsum ; 45 } 46 void build(int c, int l , int r ) 47 { 48 tree[c].l = l ; 49 tree[c].r = r; 50 tree[c].m = (l+r)/2; 51 tree[c].is3 = 0 ; 52 if(l == r) 53 { 54 tree[c].sum = 0 ; 55 tree[c].fsum = 1 ; 56 return ; 57 } 58 build(L(c),l,tree[c].m); 59 build(R(c),tree[c].m+1,r); 60 pushup(c); 61 } 62 LL ABS(LL x) 63 { 64 if(x <= 0 ) 65 return -x; 66 else return x; 67 } 68 LL find( LL x ) 69 { 70 int l = 1 , r = 85 ; 71 while(l <= r ) 72 { 73 int m = (l + r)/2; 74 if(f[m] > x) 75 { 76 r = m - 1; 77 }else { 78 l = m + 1; 79 } 80 } 81 // printf("%I64d %I64d\n",f[l],f[r]); 82 if(ABS(f[l]-x) < ABS(f[r]-x)) 83 { 84 return f[l]; 85 }else return f[r]; 86 } 87 void pushdown(int c) 88 { 89 if(tree[c].is3) 90 { 91 tree[L(c)].is3 = 1; 92 tree[R(c)].is3 = 1; 93 tree[L(c)].sum = tree[L(c)].fsum; 94 tree[R(c)].sum = tree[R(c)].fsum; 95 tree[c].is3 = 0 ; 96 } 97 } 98 void update(int c, int k , int d) 99 { 100 if(tree[c].l == tree[c].r&& tree[c].l == k ) 101 { 102 tree[c].is3 = 0 ; 103 tree[c].sum += d; 104 tree[c].fsum = find(tree[c].sum); 105 return ; 106 } 107 pushdown(c); 108 if(k <= tree[c].m) 109 update(L(c),k,d); 110 else update(R(c),k,d); 111 pushup(c); 112 } 113 LL ans = 0 ; 114 void get(int c , int l , int r) 115 { 116 if(l <= tree[c].l && r >= tree[c].r ) 117 { 118 ans += tree[c].sum ; 119 // printf("%I64d\n",ans); 120 return ; 121 } 122 pushdown(c); 123 if(l <= tree[c].m) 124 get(L(c),l,r); 125 if(r > tree[c].m) 126 get(R(c),l,r); 127 } 128 void change(int c, int l , int r) 129 { 130 if(tree[c].is3 == 1) 131 return ; 132 if(l <= tree[c].l && r >= tree[c].r) 133 { 134 tree[c].is3 = 1; 135 tree[c].sum = tree[c].fsum; 136 return ; 137 } 138 if(l <= tree[c].m) 139 change(L(c),l,r); 140 if(r > tree[c].m) 141 change(R(c),l,r); 142 pushup(c); 143 } 144 int main(){ 145 int n , m; 146 f[0] = 1 ; 147 f[1] = 1; 148 for(int i = 2;i <= 86;i ++) 149 f[i] = f[i-1] + f[i-2]; 150 while(scanf("%d %d",&n,&m) != EOF) 151 { 152 build(1 ,1,n); 153 int a, b, c ; 154 for(int i = 1;i <= m;i ++) 155 { 156 int a, b, c ; 157 scanf("%d %d %d",&a,&b,&c); 158 if(a == 1 ) 159 { 160 update(1,b,c); 161 }else if(a == 2 ){ 162 ans = 0 ; 163 get(1,b,c); 164 printf("%I64d\n",ans); 165 }else{ 166 change(1,b,c); 167 } 168 } 169 } 170 return 0; 171 }
HDU4893 Wow! Such Sequence! 线段树,布布扣,bubuko.com
时间: 2024-10-14 08:34:01