码迷,mamicode.com
首页 > 其他好文 > 详细

Wow! Such Sequence!

时间:2014-07-30 10:03:53      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:acm   线段树   

题目链接

  • 题意:
    n个点,每个初始值为零,m个操作,共三种操作:
    1 k d - "add"
    2 l r - "query sum"
    3 l r - "change to nearest Fibonacci"
    1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, |d| < 231
  • 分析:
    首先,斐波那契增长速度很快,所以题目中的数可以直接递推求出来。
    对于这个题目的区间更新操作,由于操作的特点,使得一直对一个数进行这个操作是多余的,所以记录一下当前区间如果进行了第三个操作是否会发生变化即可。
const int MAXN = 110000;

#define lson rt << 1
#define rson rt << 1 | 1

struct Node
{
    int l, r, m;
    LL sum;
    int end;
} T[MAXN << 2];

LL fib[220];
void init()
{
    fib[0] = fib[1] = 1;
    REP(i, 200)
        fib[i + 2] = fib[i] + fib[i + 1];
}
void trim(LL &n)
{
    if (n == 0)
    {
        n = 1;
        return;
    }
    int idx = lower_bound(fib, fib + 200, n) - fib;
    if (fib[idx] != n)
        n = n - fib[idx - 1] <= fib[idx] - n ? fib[idx - 1] : fib[idx];
}

void pushup(int rt)
{
    T[rt].sum = T[lson].sum + T[rson].sum;
    T[rt].end = T[lson].end & T[rson].end;
}

void build(int l, int r, int rt)
{
    T[rt].l = l; T[rt].r = r; T[rt].m = (r + l) >> 1;
    T[rt].sum = T[rt].end = 0;
    if (l == r)
    {
//        T[rt].sum = end = 0;
    }
    else
    {
        build(l, T[rt].m, lson);
        build(T[rt].m + 1, r, rson);
    }
}

void updateP(int p, int a, int rt)
{
    if (T[rt].l == T[rt].r)
    {
        T[rt].sum += a;
        T[rt].end = 0;
    }
    else
    {
        if (p <= T[rt].m)
            updateP(p, a, lson);
        else
            updateP(p, a, rson);
        pushup(rt);
    }
}

void updateS(int L, int R, int rt)
{
    if (T[rt].end)
        return;
    if (T[rt].l == T[rt].r)
    {
        trim(T[rt].sum);
        T[rt].end = 1;
    }
    else
    {
        if (L <= T[rt].m)
            updateS(L, R, lson);
        if (R > T[rt].m)
            updateS(L, R, rson);
        pushup(rt);
    }
}

LL query(int L, int R, int rt)
{
    if (L <= T[rt].l && T[rt].r <= R)
        return T[rt].sum;
    LL ret = 0;
    if (L <= T[rt].m)
        ret += query(L, R, lson);
    if (R > T[rt].m)
        ret += query(L, R, rson);
    return ret;
}

int main()
{
    int n, m, op, l, r;
    init();
    while (~RII(n, m))
    {
        build(1, n, 1);
        REP(i, m)
        {
            RIII(op, l, r);
            if (op == 1)
                updateP(l, r, 1);
            else if (op == 2)
                printf("%I64d\n", query(l, r, 1));
            else
                updateS(l, r, 1);
        }
    }
    return 0;
}


Wow! Such Sequence!,布布扣,bubuko.com

Wow! Such Sequence!

标签:acm   线段树   

原文地址:http://blog.csdn.net/wty__/article/details/38292917

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!