체육관-10071A-쿼리 (펜윅 나무)

링크 :

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

질문의 의미 :

수학자는 (심지어 미친 때때로, 나는 말할 것) 사람들이 흥미 롭다. 예를 들어, 내 친구, 수학자, 정수 번호의 순서로 플레이하는 것은 매우 재미 있다고 생각한다. 그는 행의 순서를 기록합니다. 그는 일련의 일 수를 증가하고자하는 경우, 때로는 그것을 감소하는 것이 더 재미있다 (? 왜 .. 당신이 알고) 그리고 그 간격에 번호를 추가 좋아 [L, R]. 그러나 그는 정말 멋진 것을 보여주는 그는 어떤 모드 (모듈로 m) 동일한 숫자 만 추가합니다.

그는 내가 프로그래머임을 알고 때 그가 나에게 물었다 어떻게 됐을까? 그래, 참으로, 그는 이러한 쿼리를 (n은 시퀀스의 길이) 처리 할 수있는 프로그램을 작성하는 나에게 물었다 :

  • 그것은 R로 인덱스 (P)와 수를 증가 PR. (,)
    당신은 출력의 증가 후 수 있습니다.

  • 그것은 R로 인덱스 (P)와 수를 감소 PR. 음수가 될 경우 (,) 당신은 수를 줄일 수 없습니다.
    당신은 출력의 감소 이후 수 있습니다.

일안 리플렉스 개조 당신은 동일한 출력 모드 (모듈로 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;
}

추천

출처www.cnblogs.com/YDDDD/p/11527724.html