hdu 4893 Wow! Such Sequence! (線段樹 區間更新+單點更新)
阿新 • • 發佈:2019-02-18
/* 1 k d 第k個數加d 2 l r 查詢l到r的和 3 l r l到r更新到最近的f[] */ # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; # define lson l,m,rt<<1 # define rson m+1,r,rt<<1|1 # define N 100005 __int64 sum[N<<2],need[N<<2],L[N<<2],R[N<<2]; __int64 f[110]; int col[N<<2]; __int64 find(__int64 x)//二分查詢最近f[] { if(x<=1) return 1; int left=1; int right=93; while(left<=right) { int mid=(left+right)>>1; if(f[mid]-x>0) right=mid-1; else left=mid+1; } // printf("%I64d %I64d\n",f[left],f[left-1]); //int left=lower_bound(f,f+93,x)-f; if(f[left]-x>=x-f[left-1]) return f[left-1]; return f[left]; } void PushUP(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; need[rt]=need[rt<<1]+need[rt<<1|1]; } void PushDown(int rt) { if(col[rt]!=-1) { col[rt<<1]=col[rt<<1|1]=1; sum[rt<<1]+=need[rt<<1]; sum[rt<<1|1]+=need[rt<<1|1]; need[rt<<1|1]=need[rt<<1]=0; col[rt]=-1; } } void build(int l,int r,int rt) { col[rt]=-1; sum[rt]=0; if(l==r) { need[rt]=1;//如果沒有更新過 原來是0所以最小需要1到底f[] return ; } int m=(l+r)>>1; build(lson); build(rson); PushUP(rt); } void add(int a,int val,int l,int r,int rt)//單點更新 { if(l==r) { sum[rt]+=val; col[rt]=1; need[rt]=find(sum[rt])-sum[rt]; return ; } PushDown(rt); int m=(l+r)>>1; if(a<=m) add(a,val,lson); else add(a,val,rson); PushUP(rt); } void update(int a,int b,int l,int r,int rt)//區間更新為最近且最小的斐波那契數 { if(a<=l&&b>=r) { sum[rt]+=need[rt]; col[rt]=1; need[rt]=0; return ; } PushDown(rt); int m=(l+r)>>1; if(a<=m) update(a,b,lson); if(b>m) update(a,b,rson); PushUP(rt); } __int64 query(int a,int b,int l,int r,int rt) { if(a<=l&&b>=r) { return sum[rt]; } PushDown(rt); __int64 ret=0; int m=(l+r)>>1; if(a<=m) ret+=query(a,b,lson); if(b>m) ret+=query(a,b,rson); return ret; } int main() { f[0]=1; f[1]=1; for(int i=2; i<=93; i++) { f[i]=f[i-1]+f[i-2]; } int n,m,op,b,c; while(~scanf("%d%d",&n,&m)) { build(1,n,1); while(m--) { scanf("%d%d%d",&op,&b,&c); if(op==1) { add(b,c,1,n,1); } else if(op==2) { printf("%I64d\n",query(b,c,1,n,1)); } else { update(b,c,1,n,1); } } // for(int i=1; i<=n; i++) // printf("%I64d\n",query(i,i,1,n,1)); } return 0; }