LOJ6277 number of columns of a block entry
label
Foreword
- My blog csdn and garden are synchronized, Welcome danzh- blog Park ~
- I thought that would segment tree on it, do not need to block. Now we found some problems - it is the beginning of starting a credit block chunked it
Concise meaning of the questions
- To a sequence, required to support both.
- Plus range
- A single point of inquiry
Thinking
- Here to talk about the block.
- The first sub-block of the entire sequence. Such sequences are: 1,3,2,4,5,6,7,8,9 We block, the size of each block is 3, and therefore, the first block 132 belonging to, belong to the second block 456, 789 belonging to third block. So we open a POS array [] i-th block recording element belongs. For example pos [2] = 1. So the question now is to know how to block the i-th element belongs to it? Assuming that the size of the block is len, then pos [i] = (i-1) / len + 1. Specific reasons to think of it ~
- We will put the original sequence into n / len (+1) blocks, and each time interval of operation, the cycle is not a monolithic element violent look at, a tag to open a monolithic array [] records i have not added the number of blocks is.
Precautions
- Note that the l, r in the process with a
to sum up
AC Code
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 5e4 + 10;
int n, a[maxn];
int pos[maxn], len, tag[maxn];
void add(int l, int r, int c)
{
for (int i = l; i <= min(pos[l] * len, r); i++)
a[i] += c;
if (pos[l] != pos[r])
for (int i = r; i >= max((pos[r] - 1) * len + 1, l); i--)
a[i] += c;
for (int i = pos[l] + 1; i <= pos[r] - 1; i++)
tag[i] += c;
}
void solve()
{
scanf("%d", &n);
len = sqrt(n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]), pos[i] = (i - 1) / len + 1;
for (int i = 1; i <= n; i++)
{
int opt, l, r, c;
scanf("%d%d%d%d", &opt, &l, &r, &c);
if (opt == 0)
add(l, r, c);
else
printf("%d\n", a[r] + tag[pos[r]]);
}
}
int main()
{
solve();
return 0;
}