1 1 2 1 1 5 4 1 1 7 1 3 17 3 2 4 2 1 5
0 22
存一个sumv,
和改为Fib后的fsum,
mark表示是否改为Fib数
然后线段树
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define MEM2(a,i) memset(a,i,sizeof(a)); #define INF (2139062143) #define MAXN (200000+109) #define MAXM (100000+10) typedef __int64 ll; ll f[100]; const int MFIB = 80; ll find (ll x) { if (x<=1) return 1; int m=upper_bound(f+1,f+80,x)-(f+1); if (llabs(f[m+1]-x)<llabs(f[m]-x)) m++; if (llabs(f[m-1]-x)<=llabs(f[m]-x)) m--; return f[m]; } class SegmentTree { public: ll sumv[MAXN*4],fsum[MAXN*4]; bool mark[MAXN*4]; int n; SegmentTree(){} void mem(int _n) { MEM(sumv) MEM(fsum) MEM(mark) n=_n; build(1,1,_n); } void build(int o,int L,int R) { if (L==R) { sumv[o]=mark[o]=0; fsum[o]=1; } else{ int M=(R+L)>>1; if (L<=M) build(Lson,L,M); if (M< R) build(Rson,M+1,R); } maintain(o,L,R); } void maintain(int o,int L,int R) { if (L<R) { sumv[o]=sumv[Lson]+sumv[Rson]; fsum[o]=fsum[Lson]+fsum[Rson]; } } int y1,y2,v; void update(int o,int L,int R) { pushdown(o,L,R); if (L==R) { sumv[o]+=v; fsum[o]=find(sumv[o]); mark[o]=0; return ; } else{ int M=(R+L)>>1; if (y1<=M) update(Lson,L,M); if (M< y2) update(Rson,M+1,R); } maintain(o,L,R); } void update3(int o,int L,int R) //fib { pushdown(o,L,R); if (y1<=L&&R<=y2) { mark[o]=1; sumv[o]=fsum[o]; return ; } else{ int M=(R+L)>>1; if (y1<=M) update3(Lson,L,M); //维护pushodown,再次maintain if (M< y2) update3(Rson,M+1,R); } maintain(o,L,R); } void pushdown(int o,int L,int R) { if (L>R) return; if (L==R) { mark[o]=0; return ; } if (mark[o]) { mark[Lson]= mark[ Rson ] = 1; sumv[Lson]=fsum[Lson]; sumv[Rson]=fsum[Rson]; mark[o]=0; } } ll _sum; void query2(int o,int L,int R) { pushdown(o,L,R); if (y1<=L&&R<=y2) { _sum+=sumv[o]; return; } else { int M=(L+R)>>1; if (y1<=M) query2(Lson,L,M); if (M< y2) query2(Rson,M+1,R); } } void add(int l,int r,ll v) { y1=l,y2=r;this->v=v; update(1,1,n); } void fibset(int l,int r) { y1=l,y2=r; update3(1,1,n); } ll ask(int l,int r) { _sum=0; y1=l,y2=r; query2(1,1,n); return _sum; } void print() { For(i,n) cout<<ask(i,i)<<' '; cout<<endl; } }S; int n,m; int main() { // freopen("data.in","r",stdin); // freopen("data.out","w",stdout); f[1]=f[2]=1; Fork(i,3,80) f[i] = f[i-1] + f[i-2]; // Fork(i,-10,100) cout<<i<<" "<<find(i)<<endl; while(scanf("%d%d",&n,&m)==2) { S.mem(n); For(i,m) { int p; scanf("%d",&p); if (p==1) { int k;ll d; scanf("%d%I64d",&k,&d); S.add(k,k,d); } else { int a,b; scanf("%d%d",&a,&b); if (p==2) printf("%I64d\n",S.ask(a,b)); else if (p==3) S.fibset(a,b); } // S.print(); } } return 0; }