• 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
    */
    



  • 相关阅读:
    zoj 1239 Hanoi Tower Troubles Again!
    zoj 1221 Risk
    uva 10192 Vacation
    uva 10066 The Twin Towers
    uva 531 Compromise
    uva 103 Stacking Boxes
    稳定婚姻模型
    Ants UVA
    Golden Tiger Claw UVA
    关于upper、lower bound 的探讨
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/6770385.html
Copyright © 2020-2023  润新知