링크 :
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;
}