题目
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4267
题目来源:2016.2.26群赛
简要题意:询问某数为多少,对 [l,r] 内 i−l≡0modk 的 ai 加上 c 。
题解
一开始以为是个线段树区间更新,不过后来想想整个信息没法叠加,不能这么做。
维护
55 个树状数组, bt[mod][rem] 表示模 mod 为 rem 的情况。写的时候可以编码节约空间,更新树状数组的时候要避免下标 0 ,要注意下标增加是可能超过
n 的。数据结构功力还是太差了。
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
// head
const int N = 5e4+5;
struct BIT {
#define T int
T tree[N] ;
inline int lowbit(int x) {
return x&(-x);
}
void add(int x, T add, int n) {
for (int i = x; i <= n; i += lowbit(i)) {
tree[i] += add;
}
}
T sum(int x) {
T ans = 0;
for (int i = x; i > 0; i -= lowbit(i)) {
ans += tree[i];
}
return ans;
}
void clear(int n) {
for (int i = 1; i <= n; i++) {
tree[i] = 0;
}
}
#undef T
};
struct DataStructure {
BIT bt[56];
int getBITIndex(int rem, int mod) {
return (mod - 1) * mod / 2 + rem;
}
int getPos(int x, int rem, int mod) {
return (x - rem) / mod + 1;
}
void modify(int l, int r, int mod, int v, int n) {
int rem = l % mod;
int x = getBITIndex(rem, mod);
int lb = getPos(l, rem, mod);
int ub = getPos(r, rem, mod);
bt[x].add(lb, v, n+5);
bt[x].add(ub+1, -v, n+5);
}
int query(int x) {
int ans = 0;
for (int mod = 1; mod <= 10; mod++) {
int rem = x % mod;
int pos = getBITIndex(rem, mod);
int mpos = getPos(x, rem, mod);
ans += bt[pos].sum(mpos);
}
return ans;
}
void clear(int n) {
for (int i = 0; i < 56; i++) {
bt[i].clear(n);
}
}
};
DataStructure d;
int a[N];
int main() {
int n, m, l, r, mod, v, op;
while (scanf("%d", &n) == 1) {
for (int i = 1; i <= n; i++) {
scanf("%d", a+i);
}
scanf("%d", &m);
while (m--) {
scanf("%d", &op);
if (op == 1) {
scanf("%d%d%d%d", &l, &r, &mod, &v);
d.modify(l, r, mod, v, n);
} else {
scanf("%d", &v);
printf("%d\n", a[v] + d.query(v));
}
}
d.clear(n+5);
}
return 0;
}