zoukankan      html  css  js  c++  java
  • hdu4893 Wow! Such Sequence!

    线段树结点上保存一个一般的sum值,再同一时候保存一个fbsum,表示这个结点表示的一段数字若为斐波那契数时的和

    当进行3操作时,仅仅用将sum = fbsum就可以

    其它操作照常进行,仅仅是单点更新的时候也要先向下更新


    #include <cstdio>
    #include <ctime>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    #include <string>
    #include <set>
    #include <stack>
    #include <map>
    #include <cmath>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <bitset>
    #include <fstream>
    using namespace std;
    //LOOP
    #define FF(i, a, b) for(int i = (a); i < (b); ++i)
    #define FE(i, a, b) for(int i = (a); i <= (b); ++i)
    #define FED(i, b, a) for(int i = (b); i>= (a); --i)
    #define REP(i, N) for(int i = 0; i < (N); ++i)
    #define CLR(A,value) memset(A,value,sizeof(A))
    #define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
    //OTHER
    #define SZ(V) (int)V.size()
    #define PB push_back
    #define MP make_pair
    #define all(x) (x).begin(),(x).end()
    //INPUT
    #define RI(n) scanf("%d", &n)
    #define RII(n, m) scanf("%d%d", &n, &m)
    #define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
    #define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)
    #define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)
    #define RS(s) scanf("%s", s)
    //OUTPUT
    #define WI(n) printf("%d
    ", n)
    #define WS(n) printf("%s
    ", n)
    
    #define sqr(x) (x) * (x)
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector <int> VI;
    const double eps = 1e-9;
    const int MOD = 1000000007;
    const double PI = acos(-1.0);
    //const int INF = 0x3f3f3f3f;
    const int maxn = 100010;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    #define ll rt << 1
    #define rr rt << 1 | 1
    
    struct Node{
        int l, r, m;
        LL sum, fbsum;
        bool f;
    }t[maxn * 4];
    LL fb[10000];
    int fbcnt;
    
    void  init()
    {
        fb[1] = 1, fb[0] = 1;
        for (int i = 2; ; i++)
        {
            fb[i] = fb[i - 1] + fb[i - 2];
            if (fb[i] > INF)
            {
                fbcnt = i - 1;
                return;
            }
        }
        return;
    }
    
    void push_up(int rt)
    {
        t[rt].sum = t[ll].sum + t[rr].sum;
        t[rt].fbsum = t[ll].fbsum + t[rr].fbsum;
        t[rt].f = t[ll].f & t[rr].f;
    }
    
    LL get(LL x)
    {
        int pos = lower_bound(fb, fb + fbcnt, x) - fb;
        if (pos && abs(fb[pos - 1] - x) <= abs(fb[pos] - x))
            return fb[pos - 1];
        return fb[pos];
    }
    
    void push_down(int rt)
    {
        if (t[rt].f)
        {
            t[ll].sum = t[ll].fbsum;
            t[rr].sum = t[rr].fbsum;
            t[rr].f = t[ll].f = 1;
            t[rt].f = 0;
        }
    }
    
    void build(int l, int r, int rt)
    {
        t[rt].l = l, t[rt].r = r, t[rt].m = (l + r) >> 1;
        if (l == r)
        {
            t[rt].sum = 0;
            t[rt].fbsum = 1;
            t[rt].f = 0;
            return;
        }
        build(l, t[rt].m, ll);
        build(t[rt].m + 1, r, rr);
        push_up(rt);
    }
    
    void update(int x, int add, int rt)
    {
        if (x == t[rt].l && t[rt].r == x)
        {
            t[rt].sum += add;
            t[rt].fbsum = get(t[rt].sum);
            t[rt].f = 0;
            return;
        }
        push_down(rt);
        if (x <= t[rt].m)
            update(x, add, ll);
        else
            update(x, add, rr);
        push_up(rt);
    }
    
    void updatefb(int l, int r, int rt)
    {
        if (l <= t[rt].l && r >= t[rt].r)
        {
            t[rt].sum = t[rt].fbsum;
            t[rt].f = 1;
            return;
        }
        push_down(rt);
        if (l <= t[rt].m)
            updatefb(l, r, ll);
        if (r > t[rt].m)
            updatefb(l, r, rr);
        push_up(rt);
    }
    
    LL query(int l, int r, int rt)
    {
        if (l <= t[rt].l && r >= t[rt].r)
            return t[rt].sum;
        push_down(rt);
        LL ans = 0;
        if (l <= t[rt].m)
            ans += query(l, r, ll);
        if (r > t[rt].m)
            ans += query(l, r, rr);
        return ans;
    }
    
    int main()
    {
        init();
        int n, m;
        while (~RII(n, m))
        {
            build(1, n, 1);
            int x, y, op;
            while (m--)
            {
                RIII(op, x, y);
                if (op == 1)
                    update(x, y, 1);
                else if (op == 2)
                    printf("%I64d
    ", query(x, y, 1));
                else
                    updatefb(x, y, 1);
            }
        }
        return 0;
    }
    /*
    5 4
    3 1 3
    2 1 3
    1 3 3
    2 1 3
    
    5 2
    3 1 3
    2 1 2
    */
    



  • 相关阅读:
    [视频教程] 如何在docker环境下的纯净ubuntu系统中安装最新版nginx
    [视频教程] 如何在Linux深度系统deepin下安装docker
    某业务自助开通账户问题排查
    将博客搬至CSDN
    某业务付费统计脚本问题排查
    [PHP] 存储改造中的逻辑和清理遗留的问题
    [PHP] 运维新增服务器导致的附件上传失败问题
    [PHP] 近期接手現有的企邮前端框架业务所遇困难
    [Linux] 编写Dockerfile文件自动构建镜像
    [PHP] 持续交付Jenkins安装
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/6770385.html
Copyright © 2011-2022 走看看