Wow! Such Sequence!

题目链接

  • 题意:

    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!

时间: 2024-08-15 09:40:08

Wow! Such Sequence!的相关文章

hdu 4893 Wow! Such Sequence!(线段树)

题目链接:hdu 4983 Wow! Such Sequence! 题目大意:就是三种操作 1 k d, 修改k的为值增加d 2 l r, 查询l到r的区间和 3 l r, 间l到r区间上的所以数变成最近的斐波那契数,相等的话取向下取. 解题思路:线段树,对于每个节点新增一个bool表示该节点以下的位置是否都是斐波那契数. #include <cstdio> #include <cstring> #include <cstdlib> #include <algor

hdu 4893 (多校1007)Wow! Such Sequence!(线段树&amp;二分&amp;思维)

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 352    Accepted Submission(s): 104 Problem Description Recently, Doge got a funny birthday present from his new friend, Prot

HDU 4893 Wow! Such Sequence! 水线段树

思路: 线段树走起.. 写完这题就退役T^T 单点更新的时候直接找到这个点的最近fib,然后维护当前和 和 fib的和 #include<stdio.h> #include<string.h> #include<iostream> #include<math.h> #include<algorithm> #include<queue> #include<map> #include<set> #include&l

hdu 4893 Wow! Such Sequence!(线段树功能:单点更新,区间更新相邻较小斐波那契数)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 --------------------------------------------------------------------------------------------------------------------------------------------

HDOJ 4893 Wow! Such Sequence!

题意是这样的,给定一个n个元素的数组,初始值为0,3种操作: 1 k d将第k个数增加d: 2 l r 询问区间l...r范围内数之和: 3 l r 表示将区间l...r内的数变成离他最近的斐波那契数,要求尽量小. 线段树操作题目,其中对于第三种操作用一个懒惰标记一下,表示l...r内的数是不是已经变成斐波那契数,如果是的话,求和就是其相应数的斐波那契数之和. 代码: 1 //Template updates date: 20140718 2 #include <bits/stdc++.h>

HDOJ 4893 Wow! Such Sequence! 线段树

http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:10万的区间,初始都为0,10万次操作,三种操作为单点修改,区间将每个数改成最近的斐波那契数,以及区间求和. 分析:用一个flag记录该段是否被改成斐波那契数,同时多维护一个sum1表示如果该段改成斐波那契数,区间和为多少.开始sum1为区间长度,之后在单点做了修改以后对其更新,需要的时候用其覆盖sum. 1 #include<cstdio> 2 #include<cstring>

Wow! Such Sequence! (线段树) hdu4893

http://acm.hdu.edu.cn/showproblem.php?pid=4893 先贴上一份还没过的代码,不知道拿出错了  1 // by caonima 2 // hehe  3 #include <cstring>  4 #include <algorithm>  5 #include <cstdio>  6 #include <queue>  7 #include <stack>  8 #include <vector&g

HDU4893 Wow! Such Sequence! 线段树

题意:给你一个序列,其中有三种操作 1)位置为K 的数+ D 2)求 l-r 区间和 3)把 l-r 区间里面的所有数都变为理它最近的斐波纳契数 解题思路:这个题的区间更新其实可以在单点更新的时候就得出,为节点维护两个 和,一个是 斐波纳契和 一个是正常和 ,再看这个区间有没有被3覆盖,特判一下就行了. 解题代码: 1 // File Name: 1007.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月29日 星期二 12时49分33

2014多校3 Wow! Such Sequence!线段树

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 这题实在是让人纠结啊--好久不写线段树的题了,因为这几天学伸展树,然后觉得线段树小case了.没想到栽在这题上了.尼玛-- 自己把自己给搞晕了--想复杂了,都不懂得预处理一下,唉--还得怒刷几十道啊!! #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #in

HDU 4893 Wow! Such Sequence! (线段树)

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 838    Accepted Submission(s): 245 Problem Description Recently, Doge got a funny birthday present from his new friend, Prot