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


    链接: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
    ",ans);
                }
                else{
                    update2(l,r,1,n,1);
                }
            }
        }
        return 0;
    }
    


  • 相关阅读:
    费马定理
    JAVA大数模板
    扩展KMP模板
    KMP算法模板
    2018暑假遗留题目
    线段树模板(含区间最大(小)值)
    [USACO18OPEN]Out of Sorts G
    几道背包题
    两个有关素数的算法
    German Collegiate Programming Contest 2015 F. Divisions
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/6791276.html
Copyright © 2020-2023  润新知