HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】

来源:互联网 发布:淘宝卖家怎样申诉 编辑:程序博客网 时间:2024/06/05 05:29

链接: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|1long 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;}


1 0
原创粉丝点击