[HDOJ 4893] Wow! Such Sequence! [线段树]
2014-08-01 19:03
288 查看
给定一个序列,现有3种操作:
1. 查询区间[l,r]的元素的和。
2. 将区间[l,r]元素置为最近的Fibonacci数
3. 将第x个元素加上d
线段树,维护区间和,区间都变成Fibonacci数之后的和,以及是否进了变为Fibonacci数的懒操作标记即可。
最开始因为把第3个操作看成了把第x个元素置成d..调了好久...
1. 查询区间[l,r]的元素的和。
2. 将区间[l,r]元素置为最近的Fibonacci数
3. 将第x个元素加上d
线段树,维护区间和,区间都变成Fibonacci数之后的和,以及是否进了变为Fibonacci数的懒操作标记即可。
最开始因为把第3个操作看成了把第x个元素置成d..调了好久...
#include <cstdio> #include <set> using namespace std; struct Node { long long v,vv; bool flag; Node *ls,*rs; void down() { if (!flag) return; if (ls) { ls->v=ls->vv; ls->flag=true; } if (rs) { rs->v=rs->vv; rs->flag=true; } flag=false; } void repair() { v=ls->v+rs->v; vv=ls->vv+rs->vv; } }; Node a[200100]; Node *ap,*root; int n,m; set <long long> c; long long nearstFib(long long x) { if (x<=1) return 1; set<long long>::iterator tmp=c.lower_bound(x); long long y=*tmp; tmp--; long long z=*tmp; if (y-x<x-z) return y; return z; } Node *maketree(int l,int r) { Node *ans=ap++; if (l==r) { ans->ls=ans->rs=NULL; ans->v=0; ans->vv=1; } else { int t=(l+r)/2; ans->ls=maketree(l,t); ans->rs=maketree(t+1,r); ans->repair(); } ans->flag=false; return ans; } void set1(Node *from,int l,int r,int i,int x) { if (l==r) { from->flag=false; from->v+=x; from->vv=nearstFib(from->v); } else { from->down(); int t=(l+r)/2; if (i<=t) { set1(from->ls,l,t,i,x); } else { set1(from->rs,t+1,r,i,x); } from->repair(); } } long long get(Node *from,int l,int r,int ll,int rr) { if (l==ll&&r==rr) { return from->v; } from->down(); int t=(l+r)/2; if (rr<=t) { return get(from->ls,l,t,ll,rr); } else if (ll>t) { return get(from->rs,t+1,r,ll,rr); } else { return get(from->ls,l,t,ll,t)+get(from->rs,t+1,r,t+1,rr); } } void set2(Node *from,int l,int r,int ll,int rr) { if (l==ll&&r==rr) { from->flag=true; from->v=from->vv; } else { from->down(); int t=(l+r)/2; if (rr<=t) { set2(from->ls,l,t,ll,rr); } else if (ll>t) { set2(from->rs,t+1,r,ll,rr); } else { set2(from->ls,l,t,ll,t); set2(from->rs,t+1,r,t+1,rr); } from->repair(); } } int main() { long long x,y,z; int i; x=y=1; while (y<1ll<<62) { c.insert(y); z=y; y+=x; x=z; } while (scanf("%d%d",&n,&m)!=EOF) { ap=a; root=maketree(1,n); for (i=0;i<m;i++) { int k,l,r; scanf("%d%d%d",&k,&l,&r); if (k==1) { set1(root,1,n,l,r); } else if (k==2) { printf("%lld\n",get(root,1,n,l,r)); } else if (k==3) { set2(root,1,n,l,r); } } } return 0; }
相关文章推荐
- 【线段树】 HDOJ 4893 Wow! Such Sequence!
- HDOJ 4893 Wow! Such Sequence! (线段树)
- HDOJ 4893 Wow! Such Sequence! 线段树
- HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】
- HDU 4893 Wow! Such Sequence! (线段树)
- HDU 4893 Wow! Such Sequence! 水线段树
- HDU 4893 Wow! Such Sequence! 解题报告(线段树)
- hdu 4893 Wow! Such Sequence! 线段树
- HDOJ 4893 Wow! Such Sequence!
- HDOJ 4893 Wow! Such Sequence!
- HDU 4893 Wow! Such Sequence! (线段树)
- HDU 4893 Wow! Such Sequence! (线段树)
- hdu 4893 Wow! Such Sequence! 线段树单点更新+区间更新+区间查询
- HDU 4893 Wow! Such Sequence!【线段树】
- ACM 线段树模板 hdu 4893 Wow! Such Sequence!
- HDU 4893(Wow! Such Sequence!-线段树单点修改+区间求和+改为最近Fib数)
- 【HDU 4893 多校联合】 Wow! Such Sequence!【线段树】
- hdu 4893 Wow! Such Sequence! 水线段树。
- 线段树 + 区间更新: HDU 4893 Wow! Such Sequence!
- 【HDU】4893 Wow! Such Sequence! 线段树