过了样例,只AC了第一个点
#include <stdio.h>
#include <string.h>
#include <utility>
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)
long long sequence[100008];
typedef struct _node
{
long long value;
long long lazyAdd;
} node;
class SegmentTree
{
private:
node tree[400008];
int size;
public:
SegmentTree(long long *sourceData, int sizeOfData)
{
size = sizeOfData;
build(1, size, 1);
}
void build(unsigned int left, unsigned int right, unsigned int currentNodeId)
{
tree[currentNodeId].lazyAdd = 0;
if (unlikely(left == right))
tree[currentNodeId].value = sequence[left];
else
{
auto middle = (left + right) / 2;
build(left, middle, currentNodeId * 2);
build(middle + 1, right, currentNodeId * 2 + 1);
tree[currentNodeId].value = tree[currentNodeId * 2].value + tree[currentNodeId * 2 + 1].value;
}
}
long long getSum(std::pair<unsigned int, unsigned int> queryInterval)
{
return getSum(queryInterval, std::make_pair(1, size), 1);
}
long long getSum(std::pair<unsigned int, unsigned int> queryInterval, std::pair<unsigned int, unsigned int> currentNodeInterval, unsigned int currentNodeId)
{
if (queryInterval.first <= currentNodeInterval.first && queryInterval.second >= currentNodeInterval.second)
{
fprintf(stderr, "query[%u, %u], cur->[%u, %u] = %lld\n", queryInterval.first, queryInterval.second, currentNodeInterval.first, currentNodeInterval.second, tree[currentNodeId].value);
return tree[currentNodeId].value;
}
auto middle = (currentNodeInterval.first + currentNodeInterval.second) / 2;
auto sum = 0ll;
if (tree[currentNodeId].lazyAdd)
{
tree[currentNodeId * 2].value += tree[currentNodeId].lazyAdd * (middle - currentNodeInterval.first + 1);
tree[currentNodeId * 2 + 1].value += tree[currentNodeId].lazyAdd * (currentNodeInterval.second - middle);
tree[currentNodeId * 2].lazyAdd += tree[currentNodeId].lazyAdd;
tree[currentNodeId * 2 + 1].lazyAdd += tree[currentNodeId].lazyAdd;
tree[currentNodeId].lazyAdd = 0;
}
if (queryInterval.first <= middle)
sum += getSum(queryInterval, std::make_pair(currentNodeInterval.first, middle), currentNodeId * 2);
if (queryInterval.second > middle)
sum += getSum(queryInterval, std::make_pair(middle + 1, currentNodeInterval.second), currentNodeId * 2 + 1);
fprintf(stderr, "query[%u, %u], cur->[%u, %u] = %lld\n", queryInterval.first, queryInterval.second, currentNodeInterval.first, currentNodeInterval.second, sum);
// printValue();
// printLazyAdd();
return sum;
}
void update(std::pair<unsigned int, unsigned int> operationInterval, long long changeValue)
{
return update(operationInterval, std::make_pair(1, size), 1, changeValue);
}
void update(std::pair<unsigned int, unsigned int> operationInterval, std::pair<unsigned int, unsigned int> currentNodeInterval, unsigned int currentNodeId, long long changeValue)
{
fprintf(stderr, "change %lld, [%u, %u], cur->[%u, %u] %u\n", changeValue, operationInterval.first, operationInterval.second, currentNodeInterval.first, currentNodeInterval.second, currentNodeId);
if (unlikely(operationInterval.first <= currentNodeInterval.first && operationInterval.second >= currentNodeInterval.second))
{
tree[currentNodeId].value += changeValue * (currentNodeInterval.second - currentNodeInterval.first + 1);
tree[currentNodeId].lazyAdd += changeValue;
}
else
{
auto middle = (currentNodeInterval.first + currentNodeInterval.second) / 2;
if (tree[currentNodeId].lazyAdd && currentNodeInterval.first != currentNodeInterval.second)
{
tree[currentNodeId * 2].value += changeValue * (middle - currentNodeInterval.first + 1);
tree[currentNodeId * 2 + 1].value += changeValue * (currentNodeInterval.second - middle);
tree[currentNodeId * 2].lazyAdd += tree[currentNodeId].lazyAdd;
tree[currentNodeId * 2 + 1].lazyAdd += tree[currentNodeId].lazyAdd;
tree[currentNodeId].lazyAdd = 0;
}
if (operationInterval.first <= middle)
update(operationInterval, std::make_pair(currentNodeInterval.first, middle), currentNodeId * 2, changeValue);
if (operationInterval.second > middle)
update(operationInterval, std::make_pair(middle + 1, currentNodeInterval.second), currentNodeId * 2 + 1, changeValue);
tree[currentNodeId].value = tree[currentNodeId * 2].value + tree[currentNodeId * 2 + 1].value;
}
}
void printValue()
{
fprintf(stderr, "--value--");
for (auto &v : tree)
{
if (&v == tree + 4*size-5)
break;
fprintf(stderr, " %lld", v.value);
}
fprintf(stderr, "\n");
}
void printLazyAdd()
{
fprintf(stderr, "--lazy-add--");
for (auto &v : tree)
{
if (&v == tree + 4*size-5)
break;
fprintf(stderr, " %lld", v.lazyAdd);
}
fprintf(stderr, "\n");
}
};
int main()
{
#ifdef DEBUG
freopen("seg.in", "r", stdin);
#endif
int countOfNumber, countOfOperations;
scanf("%d %d", &countOfNumber, &countOfOperations);
for (auto i = 1; i <= countOfNumber; i++)
scanf("%lld", &sequence[i]);
auto segmentTree = new SegmentTree(sequence, countOfNumber);
for (auto i = 0; i < countOfOperations; i++)
{
auto operation = 0u, left = 0u, right = 0u;
auto changeValue = 0ll;
scanf("%u", &operation);
if (operation == 1)
{
scanf("%u %u %lld", &left, &right, &changeValue);
segmentTree->update(std::make_pair(left, right), changeValue);
}
else
{
scanf("%u %u", &left, &right);
printf("%lld\n", segmentTree->getSum(std::make_pair(left, right)));
}
}
return 0;
}