Gym-10071A-Queries(树状数组)

我是研究僧i 提交于 2019-11-29 19:10:17

链接:

https://vjudge.net/problem/Gym-100741A

题意:

Mathematicians are interesting (sometimes, I would say, even crazy) people. For example, my friend, a mathematician, thinks that it is very fun to play with a sequence of integer numbers. He writes the sequence in a row. If he wants he increases one number of the sequence, sometimes it is more interesting to decrease it (do you know why?..) And he likes to add the numbers in the interval [l;r]. But showing that he is really cool he adds only numbers which are equal some mod (modulo m).

Guess what he asked me, when he knew that I am a programmer? Yep, indeed, he asked me to write a program which could process these queries (n is the length of the sequence):

  • p r It increases the number with index p by r. (, )
    You have to output the number after the increase.

  • p r It decreases the number with index p by r. (, ) You must not decrease the number if it would become negative.
    You have to output the number after the decrease.

s l r mod You have to output the sum of numbers in the interval which are equal mod (modulo m). () ()

思路:

看半天没看懂题.
建10个树状数组即可, 对模m的每种情况分别统计.

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
//#include <memory.h>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <stack>
#include <string>
#include <assert.h>
#include <iomanip>
#define MINF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int INF = 1e9;

const int MAXN = 1e4+10;
LL A[MAXN], C[15][MAXN];
int n, m, q;

int Lowbit(int x)
{
    return x&(-x);
}

void Add(int pos, int mod, LL val)
{
    while (pos <= n)
    {
        C[mod][pos] += val;
        pos += Lowbit(pos);
    }
}

LL Query(int pos, int mod)
{
    LL ans = 0;
    while (pos > 0)
    {
        ans += C[mod][pos];
        pos -= Lowbit(pos);
    }
    return ans;
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1;i <= n;i++)
    {
        scanf("%lld", &A[i]);
        Add(i, A[i]%m, A[i]);
    }
    scanf("%d", &q);
    char opt[5];
    int l, r, mod;
    while (q--)
    {
        scanf("%s", opt);
        if (opt[0] == 's')
        {
            scanf("%d%d%d", &l, &r, &mod);
            printf("%lld\n", Query(r, mod)-Query(l-1, mod));
        }
        else if (opt[0] == '+')
        {
            scanf("%d%d", &l, &r);
            Add(l, A[l]%m, -A[l]);
            A[l] += r;
            Add(l, A[l]%m, A[l]);
            printf("%lld\n", A[l]);
        }
        else
        {
            scanf("%d%d", &l, &r);
            Add(l, A[l]%m, -A[l]);
            if (r <= A[l])
                A[l] -= r;
            Add(l, A[l]%m, A[l]);
            printf("%lld\n", A[l]);
        }
    }

    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!