链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893
题意:给你一个长度n的数列,初始都为0,有三种操作,第一种给第k个位置的数加d,第二种是查询区间 [l , r] 的总和,第三种是使区间 [l , r] 的值改为离它最近的那个斐波那契数的值。
我刚开始用sum数组存储节点的值,第三种操作是个区间更新,但是区间更新的值不一样,我就想当然的搜到最底部的节点来处理更新,果断T了。后来想了想,其实可以在节点上再加一个信息,就是这个值下次进行第三种操作要变成的值,在每次进行第一种操作时进行这个值得更新,区间也一样存储下次变化后的总值,这样在进行第三种操作时就可以进行区间更新了比较省时,我不习惯用结构体写,所以多定义了一个数组。
sum数组存储正常值,fuck数组存储下次要变成的斐波那契值,col数组只起标记作用。
其实这题就是简单的单点更新和区间更新,合到了一起,我还是做的太少,没有在单点更新和区间查询中加pushdown,WA了两发。
#include<cstring> #include<string> #include<fstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cctype> #include<algorithm> #include<queue> #include<map> #include<set> #include<vector> #include<stack> #include<ctime> #include<cstdlib> #include<functional> #include<cmath> using namespace std; #define PI acos(-1.0) #define MAXN 100100 #define eps 1e-11 #define INF 0x7FFFFFFF #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 long long sum[MAXN<<2]; long long col[MAXN<<2]; long long fuck[MAXN<<2]; long long n,m; long long f[100]; void pushup(long long rt){ sum[rt] = sum[rt<<1] + sum[rt<<1|1]; fuck[rt] = fuck[rt<<1] + fuck[rt<<1|1]; } void pushdown(long long rt,long long m){ if(col[rt]){ col[rt<<1] = fuck[rt<<1]; col[rt<<1|1] = fuck[rt<<1|1]; sum[rt<<1] = fuck[rt<<1]; sum[rt<<1|1] = fuck[rt<<1|1]; col[rt] = 0; } } void build(long long l,long long r,long long rt){ col[rt] = 0; if(l==r){ sum[rt] = 0; fuck[rt] = 1; return ; } long long m = (l+r)>>1; build(lson); build(rson); pushup(rt); } void update(long long pos,long long add,long long l,long long r,long long rt){ if(l==r){ sum[rt] += add; long long p = lower_bound(f,f+90,sum[rt])-f; if(p-1>=0){ long long fp1 = f[p] - sum[rt]; if(fp1<0) fp1 = -fp1; long long fp2 = f[p-1] - sum[rt]; if(fp2<0) fp2 = -fp2; if(fp1>=fp2) fuck[rt] = f[p-1]; else fuck[rt] = f[p]; } else fuck[rt] = f[p]; return ; } pushdown(rt,r-l+1); long long m = (l+r)>>1; if(pos<=m) update(pos,add,lson); else update(pos,add,rson); pushup(rt); } void update2(long long L,long long R,long long l,long long r,long long rt){ if(L<=l&&r<=R){ col[rt] = fuck[rt]; sum[rt] = fuck[rt]; return ; } pushdown(rt,r-l+1); long long m = (l+r)>>1; if(L<=m) update2(L,R,lson); if(R>m) update2(L,R,rson); pushup(rt); } long long query(long long L,long long R,long long l,long long r,long long rt){ if(L<=l&&r<=R){ return sum[rt]; } pushdown(rt,rt-l+1); long long ans = 0; long long m = (l+r)>>1; if(L<=m) ans += query(L,R,lson); if(R>m) ans += query(L,R,rson); return ans; } int main(){ long long i,j,l,r,k,d,x; f[0] = 1; f[1] = 1; for(i=2;i<90;i++){ f[i] = f[i-1] + f[i-2]; } while(scanf("%I64d%I64d",&n,&m)!=EOF){ build(1,n,1); while(m--){ scanf("%I64d%I64d%I64d",&x,&l,&r); if(x==1){ update(l,r,1,n,1); } else if(x==2){ long long ans = query(l,r,1,n,1); printf("%I64d\n",ans); } else{ update2(l,r,1,n,1); } } } return 0; }
HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】,布布扣,bubuko.com
HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】
原文地址:http://blog.csdn.net/zzzz40/article/details/38276037