• hdu 4983 线段树+斐波那契数


    http://acm.hdu.edu.cn/showproblem.php?pid=4893

    三种操作:

    1 k d, 修改k的为值增加d

    2 l r, 查询l到r的区间和

    3 l r, 从l到r区间上的所以数变成最近的斐波那契数,相等的话取向下取。


    就是线段树搞,每个节点lazy表示该节点以下的位置是否都是斐波那契数,找比x小的斐波那契数使用lower_bound+加特判最近即可

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <queue>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define RD(x) scanf("%d",&x)
    #define RD2(x,y) scanf("%d%d",&x,&y)
    #define clr0(x) memset(x,0,sizeof(x))
    typedef long long LL;
    const int N = 100005;
    const LL inf = 1LL<<60;
    
    struct node
    {
        int lazy;
        LL sum,r;
    }s[N<<3];
    LL c[N];
    LL f[1500];
    void build(int l,int r,int root)
    {
        s[root].sum = 0;
        s[root].r = r - l + 1;
        s[root].lazy = 0;
        if(l == r){
            return;
        }
        int mid = (l+r)>>1;
        build(l,mid,root<<1);
        build(mid+1,r,(root<<1)+1);
        return;
    }
    LL check(LL x){
        int t = lower_bound(f,f+1426,x) - f;
        long long delta = abs(f[t]-x);
        if (t > 0 && abs(f[t-1] - x) <= delta) --t;
        return f[t];
    }
    void update(int root)
    {
        s[root].sum = s[root<<1].sum + s[root<<1|1].sum;
        s[root].r = s[root<<1].r + s[root<<1|1].r;
    }
    void insert(int l,int r,int root,int index,int v)
    {
        if(l == r){
            s[root].sum += v;
            s[root].r = check(s[root].sum);
            return;
        }
        if(s[root].lazy){
            s[root<<1].lazy = 1;
            s[root<<1].sum = s[root<<1].r;
            s[root<<1|1].lazy = 1;
            s[root<<1|1].sum = s[root<<1|1].r;
            s[root].lazy = 0;
        }
        int mid = (l+r)>>1;
        if(mid >= index)
            insert(l,mid,root<<1,index,v);
        else
            insert(mid+1,r,(root<<1)+1,index,v);
        update(root);
    }
    LL query(int l , int r , int root , int ll , int rr){
        if (l > rr || r < ll) return 0;
        if(s[root].lazy){
            s[root<<1].lazy = 1;
            s[root<<1].sum = s[root<<1].r;
            s[root<<1|1].lazy = 1;
            s[root<<1|1].sum = s[root<<1|1].r;
            s[root].lazy = 0;
        }
        if (ll <= l && rr >= r) return s[root].sum;
        int mid = (l+r)>>1;
        return query(l,mid,root<<1,ll,rr) + query(mid+1,r,(root<<1)+1,ll,rr);
    }
    void change(int l , int r , int root, int ll , int rr){
        if (l > rr || r < ll) return;
        if (ll <= l && rr >= r){
               s[root].lazy = 1;
               s[root].sum = s[root].r;
               return;
        }
        if(s[root].lazy){
            s[root<<1].lazy = 1;
            s[root<<1].sum = s[root<<1].r;
            s[root<<1|1].lazy = 1;
            s[root<<1|1].sum = s[root<<1|1].r;
            s[root].lazy = 0;
        }
        int mid = (l+r)>>1;
        change(l,mid,root<<1,ll,rr);
        change(mid+1,r,(root<<1)+1,ll,rr);
        update(root);
    }
    int main()
    {
        f[0] = f[1] = 1LL;
        int i;
        for(i = 2;i < 1426;++i)
            f[i] = f[i-1]+f[i-2];
        int n,m;
        while(~RD2(n,m)){
            clr0(c);
            build(1,n,1);
            int l,r,q;
            while(m--){
                scanf("%d%d%d",&q,&l,&r);
                if(q == 1)
                    insert(1,n,1,l,r);
                else if(q == 2)
                    printf("%I64d
    ",query(1,n,1,l,r));
                else
                    change(1,n,1,l,r);
            }
        }
        return 0;
    }


  • 相关阅读:
    iOS AFNetworking 2.6.0框架导入报错解决方法
    GitHub 上都有哪些值得关注学习的 iOS 开源项目?
    iOS开发ARC机制下的内存管理技术要点
    UIColor延伸:判断两个颜色是否相等
    iOS中的单例模式
    明天再整理,睡觉!
    pushViewController:animated:的问题
    解决UINavigationController在pushViewController时出现的"卡顿"问题
    在某OC字符串中,搜索指定的某字符串:-rangeOfString:
    SSH整合redis和MongoDB错误笔记
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4046765.html
Copyright © 2020-2023  润新知