zoukankan      html  css  js  c++  java
  • 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;
    }


  • 相关阅读:
    jquery的动画函数animate()讲解一
    用js来实现页面的换肤功能(带cookie记忆)
    Extjs换肤+cookie皮肤记忆功能
    jquery换肤
    bootstrap的alert提示框的关闭后再显示问题
    jquery.cookie中的操作
    CSS中设置margin:0 auto; 水平居中无效的原因分析
    jQuery 遍历 json 方法大全
    jquery.min.map 404 (Not Found)出错的原因及解决办法
    AJAX 跨域请求的解决办法:使用 JSONP获取JSON数据
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4046765.html
Copyright © 2011-2022 走看看