【map + 线段树】 hdu4893

本文深入探讨了深度学习在人工智能领域的应用,包括图像处理、音视频处理、自然语言处理等多个方面,详细介绍了相关算法和技术的原理、实现及实际案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Wow! Such Sequence!



Problem Description
Recently, Doge got a funny birthday present from his new friend, Protein Tiger from St. Beeze College. No, not cactuses. It's a mysterious blackbox.

After some research, Doge found that the box is maintaining a sequence an of n numbers internally, initially all numbers are zero, and there are THREE "operations":

1.Add d to the k-th number of the sequence.
2.Query the sum of ai where l ≤ i ≤ r.
3.Change ai to the nearest Fibonacci number, where l ≤ i ≤ r.
4.Play sound "Chee-rio!", a bit useless.

Let F0 = 1,F1 = 1,Fibonacci number Fn is defined as Fn = Fn - 1 + Fn - 2 for n ≥ 2.

Nearest Fibonacci number of number x means the smallest Fn where |Fn - x| is also smallest.

Doge doesn't believe the machine could respond each request in less than 10ms. Help Doge figure out the reason.
 

Input
Input contains several test cases, please process till EOF.
For each test case, there will be one line containing two integers n, m.
Next m lines, each line indicates a query:

1 k d - "add"
2 l r - "query sum"
3 l r - "change to nearest Fibonacci"

1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, |d| < 231, all queries will be valid.
 

Output
For each Type 2 ("query sum") operation, output one line containing an integer represent the answer of this query.
 

Sample Input
1 1 2 1 1 5 4 1 1 7 1 3 17 3 2 4 2 1 5
 

Sample Output
0 22
 题意:

   给出 n(1 ~ 100000),m (1 ~ 100000) ,代表存在一个初始化为 0 ,数量为 n 的数列,后给出 m 个操作。

   1 a b,代表将数列中第 k 个数增加 b( -2 ^ 31 <= b <= 2 ^ 31);

   2 a b,代表输出数列 a 到 b 的总和;

   3 a b,代表将数列 l 到 r 区间的数更改成最近的斐波那契数。

   输出所有 2 操作的结果。

表示是单点更新……但是我们可以知道其实每次要更新的节点就是那些不是斐波那契数的……
如果我们能维护出a到b哪些点是需要更新的这样更新的复杂度就降下来了——这个地方可以用map……
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
long long fib[] ={1LL,1LL,2LL,3LL,5LL,8LL,13LL,21LL,34LL,55LL,
89LL,144LL,233LL,377LL,610LL,987LL,1597LL,2584LL,4181LL,6765LL,
10946LL,17711LL,28657LL,46368LL,75025LL,121393LL,196418LL,317811LL,514229LL,832040LL,
1346269LL,2178309LL,3524578LL,5702887LL,9227465LL,14930352LL,24157817LL,39088169LL,63245986LL,102334155LL,
165580141LL,267914296LL,433494437LL,701408733LL,1134903170LL,1836311903LL,2971215073LL,4807526976LL,7778742049LL,12586269025LL,
20365011074LL,32951280099LL,53316291173LL,86267571272LL,139583862445LL,225851433717LL,365435296162LL,591286729879LL,956722026041LL,1548008755920LL,
2504730781961LL,4052739537881LL,6557470319842LL,10610209857723LL,17167680177565LL,27777890035288LL,44945570212853LL,72723460248141LL,117669030460994LL,190392490709135LL,
308061521170129LL,498454011879264LL,806515533049393LL,1304969544928657LL,2111485077978050LL,3416454622906707LL,5527939700884757LL,8944394323791464LL,14472334024676221LL,23416728348467685LL,
37889062373143906LL,61305790721611591LL,99194853094755497LL,160500643816367088LL,259695496911122585LL,420196140727489673LL,679891637638612258LL,1100087778366101931LL,1779979416004714189LL,2880067194370816120LL,
4660046610375530309LL,7540113804746346429LL
};
long long tree[100000 * 4 + 17];
long long a[100017];
int n, m;
map <long long, long long> changes;
void add(int p, int l, int r, long long x,long long num)
{
    
    if (l == r){tree[p] += num; return;}
    int mid = (l + r) / 2;
    if (x <= mid) add(p * 2, l, mid, x, num);
    else add(p * 2 + 1, mid + 1, r, x, num);
    tree[p] = tree[p * 2] + tree[p * 2 + 1];
    
}

long long find(int p, int l, int r, int x, int y)
{
    if (x <= l && r <= y)return tree[p];
    int mid = (l + r) / 2;
    if (y <= mid) return find(p * 2, l, mid, x, y);
    if (x > mid)  return find(p * 2 + 1, mid + 1, r, x, y);
    return (find (p * 2, l, mid, x, mid) + find(p * 2 + 1, mid + 1, r, mid + 1, y));
}
long long near(long long t)
{
    int p = lower_bound(fib, fib + 92, t) - fib;
    if(p==0) return fib[p];
    if(fib[p]-t>=t-fib[p-1]) p--;
    return fib[p];
}
int main()
{
    while (scanf("%d%d", &n, &m) != EOF)
    {
        memset(tree, 0, sizeof(tree));
        memset(a, 0, sizeof(a));
        changes.clear();
        for (int i = 1; i <= n; i++)
            changes.insert(pair<long long, long long>(i, 1));
        for (int i = 1; i <= m; i++)
        {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            if (x == 1)
            {
                add(1, 1, n, y, z);
                a[y] += z;
                long long  tmp = near(a[y]);
                if(tmp != a[y]) changes[y] = tmp - a[y];
            }
            if (x == 2)
            {
                //for (int j = 1; j <= 4 * n; j++)
                //cout << tree[j] << ' ';
                cout << find(1, 1, n, y, z) << endl;
            }
            if (x == 3)
            {
                map<long long, long long>::iterator t1, t2;
                t1 = changes.lower_bound(y);
                t2 = changes.upper_bound(z);
                for ( map<long long, long long>::iterator p = t1; p != t2; p++)
                {
                    a[p->first] += p->second;
                    add(1, 1, n, p->first, p->second);
                }
                changes.erase(t1, t2);
            }
            
        }
    }
    return 0;
}


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值