标签:线段树
http://acm.hdu.edu.cn/showproblem.php?pid=4893
三种操作:
1 k d - "add"
2 l r - "query sum"
3 l r - "change to nearest Fibonacci"
节点附件三个值:
s1:由lazy控制的区间的正确的和。
s2:区间内与所有数相近的fib数之和,随着单点更新而更新。
col:lazy,标记区间是否全部取fib数,是取1,否则取0。
询问区间的和时,找到相应区间直接返回s1,若有col为1的区间要先向下推送,表示要取该区间的fib数的和。
Mark.....
#include <stdio.h> #include <iostream> #include <map> #include <set> #include <stack> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #include <algorithm> #define LL long long #define _LL __int64 #define eps 1e-12 #define PI acos(-1.0) #define C 240 #define S 20 using namespace std; const int maxn = 100010; const int INF = 1 << 30; _LL fib[86]; void init() { fib[0] = fib[1] = 1; for(int i = 2; i <= 85; i++) fib[i] = fib[i-1] + fib[i-2]; } _LL Binsearch(_LL key) { int low = 0,high = 85; while(low <= high) { int mid = (low + high) >> 1; if(fib[mid] > key) high = mid-1; else low = mid+1; } if(fabs(fib[low]-key) < fabs(fib[high]-key)) return fib[low]; else return fib[high]; /*_LL Min = abs(fib[0]-key); int pos = 0; for(int i = 1; i <= 85; i++) { if(Min > abs(fib[i]-key)) { Min = abs(fib[i]-key); pos = i; } } return fib[pos];*/ } struct node { int l, r; LL s1,s2; int col; }tree[maxn*4]; void build(int v, int l, int r) { tree[v].l = l; tree[v].r = r; tree[v].col = 0; tree[v].s1 = 0; tree[v].s2 = r-l+1; if(l == r) { return; } int mid = (l+r)>>1; build(v*2,l,mid); build(v*2+1,mid+1,r); } void update_fib(int v, int l, int r) { if(tree[v].l == l && tree[v].r == r) { tree[v].col = 1; tree[v].s1 = tree[v].s2; return; } if(tree[v].col == 1) return; int mid = (tree[v].l + tree[v].r) >> 1; if(r <= mid) update_fib(v*2,l,r); else if(l > mid) update_fib(v*2+1,l,r); else { update_fib(v*2,l,mid); update_fib(v*2+1,mid+1,r); } tree[v].s1 = tree[v*2].s1 + tree[v*2+1].s1; tree[v].s2 = tree[v*2].s2 + tree[v*2+1].s2; } void update(int v, int pos, _LL d) { if(tree[v].l == tree[v].r) { tree[v].s1 += d; tree[v].s2 = Binsearch(tree[v].s1); return; } if(tree[v].col == 1) { int mid = (tree[v].l + tree[v].r) >> 1; update_fib(v*2,tree[v].l,mid); update_fib(v*2+1,mid+1,tree[v].r); tree[v].col = 0; } int mid = (tree[v].l + tree[v].r) >> 1 ; if(pos <= mid) update(v*2,pos,d); else update(v*2+1,pos,d); tree[v].s1 = tree[v*2].s1 + tree[v*2+1].s1; tree[v].s2 = tree[v*2].s2 + tree[v*2+1].s2; } _LL query(int v, int l, int r) { if(tree[v].l == l && tree[v].r == r) { return tree[v].s1; } if(tree[v].col == 1) { int mid = (tree[v].l+tree[v].r)>>1; update_fib(v*2,tree[v].l,mid); update_fib(v*2+1,mid+1,tree[v].r); tree[v].col = 0; } int mid = (tree[v].l + tree[v].r) >> 1; if(r <= mid) return query(v*2,l,r); else if(l > mid) return query(v*2+1,l,r); else return query(v*2,l,mid) + query(v*2+1,mid+1,r); } int main() { init(); int n,m; int num,l,r,pos; _LL d; while(~scanf("%d %d",&n,&m)) { build(1,1,n); while(m--) { scanf("%d",&num); if(num == 1) { scanf("%d %I64d",&pos,&d); update(1,pos,d); // for(int i = 1; i <= 3; i++) // printf("l : %2d r : %2d col : %2d s1 : %I64d s2 : %I64d\n",tree[i].l,tree[i].r,tree[i].col,tree[i].s1,tree[i].s2); } else if(num == 2) { scanf("%d %d",&l,&r); printf("%I64d\n",query(1,l,r)); } else { scanf("%d %d",&l,&r); update_fib(1,l,r); // for(int i = 1; i <= 3; i++) // printf("l : %2d r : %2d col : %2d s1 : %I64d s2 : %I64d\n",tree[i].l,tree[i].r,tree[i].col,tree[i].s1,tree[i].s2); } } } return 0; }
hdu 4893 Wow! Such Sequence!,布布扣,bubuko.com
标签:线段树
原文地址:http://blog.csdn.net/u013081425/article/details/38379215