[HDOJ 4893] Wow! Such Sequence! [线段树]

来源:互联网 发布:为什么淘宝衣服很便宜 编辑:程序博客网 时间:2024/06/04 20:10

给定一个序列,现有3种操作:

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;}


0 0
原创粉丝点击