HDU:4893 Wow! Such Sequence!(线段树单点更新+区间求和)
2015-04-21 10:11
525 查看
题意:执行相应的4种操作。
思路:单点更新时求最近fib,维护fib的和及元素的和。注意初始化的时候要对每个0求fib。
思路:单点更新时求最近fib,维护fib的和及元素的和。注意初始化的时候要对每个0求fib。
#include<iostream> #include<vector> #include<map> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<string> #define LL long long #define MAXN 100001<<2 using namespace std; vector<LL> fib; void init() { fib.push_back(1); fib.push_back(1); int i=0; while(i<90) { fib.push_back(fib[fib.size()-2]+fib[fib.size()-1]); i++; } } LL myabs(LL a) { return a>0?a:-a; } int getPosofFib(LL val) { if(val<=0) return 0; int p=lower_bound(fib.begin(),fib.end(),val)-fib.begin(); if(p==0) return 0; LL a=myabs(fib[p]-val),b=myabs(fib[p-1]-val); if(a==b) return p-1; else if(a<b) return p; else return p-1; } struct Segment_Tree { LL sum[MAXN],fibsum[MAXN]; int tar[MAXN]; void build(int o,int L,int R) { sum[o]=tar[o]=0; if(L==R) { fibsum[o]=fib[getPosofFib(0)]; return ; } int M=(L+R)/2; build(o<<1,L,M); build(o<<1|1,M+1,R); push_up(o); } void push_up(int o) { sum[o]=sum[o<<1]+sum[o<<1|1]; fibsum[o]=fibsum[o<<1]+fibsum[o<<1|1]; } void push_down(int o) { if(tar[o]) { tar[o<<1]=tar[o<<1|1]=tar[o]; sum[o<<1]=fibsum[o<<1]; sum[o<<1|1]=fibsum[o<<1|1]; tar[o]=0; } } void add(int o,int L,int R,int p,int c) { if(L==R) { sum[o]+=c; fibsum[o]=fib[getPosofFib(sum[o])]; } else { push_down(o); int M=(L+R)/2; if(p<=M) add(o<<1,L,M,p,c); else add(o<<1|1,M+1,R,p,c); push_up(o); } } void changeFib(int o,int L,int R,int ql,int qr) { if(ql<=L&&R<=qr) { sum[o]=fibsum[o]; tar[o]=1; } else { push_down(o); int M=(L+R)/2; if(ql<=M) changeFib(o<<1,L,M,ql,qr); if(M<qr) changeFib(o<<1|1,M+1,R,ql,qr); push_up(o); } } LL query(int o,int L,int R,int ql,int qr) { if(ql<=L&&R<=qr) return sum[o]; else { push_down(o); int M=(L+R)/2; LL s=0; if(ql<=M) s+=query(o<<1,L,M,ql,qr); if(M<qr) s+=query(o<<1|1,M+1,R,ql,qr); return s; } } }; Segment_Tree tree; int main() { init(); int n,m; while(scanf("%d%d",&n,&m)!=EOF) { tree.build(1,1,n); while(m--) { int p,a,b; scanf("%d%d%d",&p,&a,&b); if(p==1) tree.add(1,1,n,a,b); else if(p==2) printf("%I64d\n",tree.query(1,1,n,a,b)); else if(p==3) tree.changeFib(1,1,n,a,b); } } return 0; }
相关文章推荐
- hdu 4893 Wow! Such Sequence! (线段树 区间更新+单点更新)
- HDU 4893 Wow! Such Sequence! (线段树单点更新+区间更新+区间查询+二分)
- hdu 4893 Wow! Such Sequence! 线段树单点更新+区间更新+区间查询
- HDU 4893(Wow! Such Sequence!-线段树单点修改+区间求和+改为最近Fib数)
- hdu 1166线段树 单点更新 区间求和
- hdu 1166 敌兵布阵(线段树之 单点更新+区间求和)
- hdu 1116 敌兵布阵 线段树 区间求和 单点更新
- hdu 3874 Necklace 线段树单点更新区间求和
- HDU 1394 Minimum Inversion Number(线段树:单点更新,区间求和)
- hdu 1166 线段树单点更新和区间求和
- hdu1394——线段树(单点更新 区间求和)
- HDU 1394 Minimum Inversion Number(线段树:单点更新,区间求和)
- hdu 1166 敌兵布阵【线段树】单点更新,区间求和
- HDU - 1394 - Minimum Inversion Number (线段树 - 单点更新,区间求和)
- hdu 1166 线段树(单点更新,区间求和)
- hdu1166 敌兵布阵(线段树单点更新+区间求和)
- 学习线段树-【线段树-单点更新,区间求和】hdu 1166 -敌兵布阵
- hdu 1166 敌兵布阵(线段树-单点更新,区间求和)
- HDU 1166-敌兵布阵(线段树:单点更新,区间求和)
- Hdu 1166 敌兵布阵 树状数组 或 线段树 单点更新,区间求和