zoukankan      html  css  js  c++  java
  • 洛谷 P3404 斐波那契(线段树)

    传送门
    首先肯定是线段树,然后问题就是怎么打标记。
    观察题目,可以发现,修改操作其实就是给一段区间加上从1到r-l+1的斐波那契数列。
    那么思路就是:预处理斐波那契数列前缀和,这样可以O(1)查询斐波那契数列和。然后打标记的时候,比如要修改[L,R],那么统一都打成L-1,然后更新的时候就可以O(1)修改sum值了。
    具体就是比如区间[l,r],那么更新时就是:
    sum[rt]=(sum[rt]+f[radd[rt]]f[l1add[rt]+p)
    可是我的代码为什么交上去是0分???
    全都是WA,一片红色。。。
    亲自造了几组小数据,模拟了一下,也没问题。。
    算了,先放代码吧:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #include<vector>
    #include<queue>
    #define ll long long
    using namespace std;
    const ll p=1e9+7;
    int n,m;
    ll sum[400001];
    int add[400001];
    ll f[400001];
    inline void pushup(int rt){
        sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%p;
    }
    inline void pushdown(int rt,int l,int r){
        if(add[rt]!=-1){
            int mid=(l+r)>>1;
            add[rt<<1]=add[rt<<1|1]=add[rt];
            sum[rt<<1]=(sum[rt<<1]+f[mid-add[rt]]-f[l-1-add[rt]]+p)%p;
            sum[rt<<1|1]=(sum[rt<<1|1]+f[r-add[rt]]-f[mid-add[rt]]+p)%p;
            add[rt]=-1;
        }
    }
    void build(int rt,int l,int r){
        add[rt]=-1;
        if(l==r){
            scanf("%lld",&sum[rt]);
            return;
        }
        int mid=(l+r)>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
        pushup(rt);
    }
    void update(int rt,int l,int r,int L,int R){
        if(l!=r)pushdown(rt,l,r);
        if(L<=l&&r<=R){
            add[rt]=L-1;
            sum[rt]=(sum[rt]+f[r-(L-1)]-f[l-(L-1)-1]+p)%p;
            return;
        }
        int mid=(l+r)>>1;
        if(L<=mid)update(rt<<1,l,mid,L,R);
        if(mid+1<=R)update(rt<<1|1,mid+1,r,L,R);
        pushup(rt);
    }
    ll query(int rt,int l,int r,int L,int R){
        if(l!=r)pushdown(rt,l,r);
        if(L<=l&&r<=R){
            return sum[rt];
        }
        int mid=(l+r)>>1;
        ll ans=0;
        if(L<=mid)ans=(ans+query(rt<<1,l,mid,L,R))%p;
        if(mid+1<=R)ans=(ans+query(rt<<1|1,mid+1,r,L,R))%p;
        return ans;
    }
    int main(){
        scanf("%d %d",&n,&m);
        f[1]=1;
        f[2]=1;
        for(int i=3;i<=n;i++){
            f[i]=(f[i-1]+f[i-2])%p;
        }
        for(int i=1;i<=n;i++){
            f[i]=(f[i]+f[i-1])%p;
        }
        build(1,1,n);
        for(int i=1;i<=m;i++){
            int opt,l,r;
            scanf("%d %d %d",&opt,&l,&r);
            if(opt==1){
                update(1,1,n,l,r);
            }
            else{
                printf("%lld
    ",query(1,1,n,l,r));
            }
        }
        return 0;
    }
  • 相关阅读:
    wp8开发时模拟器无法联网解决方法
    软件测试技术---白盒测试
    软件测试技术---代码检查,走查与评审
    简谈WP,IOS,Android智能手机OS
    软件测试技术---在软件生命周期中测试的实施
    软件测试技术---测试的基本概念
    zookeeper源码分析三LEADER与FOLLOWER同步数据流程
    zookeeper源码分析(一) 工作原理
    分布式服务框架 Zookeeper -- 管理分布式环境中的数据
    构建高并发高可用的电商平台架构实践(转)
  • 原文地址:https://www.cnblogs.com/stone41123/p/7581247.html
Copyright © 2011-2022 走看看