Pagini recente » Cod sursa (job #1185568) | Cod sursa (job #1118604) | Cod sursa (job #2616768) | Cod sursa (job #1442748) | Cod sursa (job #2150745)
#include <cstdint>
#include <fstream>
#include <vector>
using namespace std;
class Bit
{
public:
Bit(int size) : bit_(vector<uint32_t>(size + 1, 0)) {}
void Add(int node, uint32_t value);
uint32_t GetSum(int left, int right) const;
int RightBoundary(uint32_t sum) const;
private:
static int Lsb(int x) { return x & -x; }
uint32_t GetSum(int right) const;
vector<uint32_t> bit_;
};
void Bit::Add(int node, uint32_t value)
{
while (node < (int)bit_.size()) {
bit_[node] += value;
node += Lsb(node);
}
}
uint32_t Bit::GetSum(int left, int right) const
{
return GetSum(right) - GetSum(left - 1);
}
int Bit::RightBoundary(uint32_t sum) const
{
int pos = 0;
int pow = (1 << 25);
while (pow > 0) {
if (pos + pow < (int)bit_.size()) {
auto curr_sum = GetSum(pos + pow);
if (curr_sum < sum) {
pos += pow;
}
}
pow -= 1;
}
return pos + 1;
}
uint32_t Bit::GetSum(int right) const
{
uint32_t sum = 0;
while (right > 0) {
sum += bit_[right];
right -= Lsb(right);
}
return sum;
}
int main()
{
ifstream fin("aib.in");
ofstream fout("aib.out");
int size, queries;
fin >> size >> queries;
Bit bit(size);
for (int i = 1; i <= size; ++i) {
uint32_t num;
fin >> num;
bit.Add(i, num);
}
for (int i = 0; i < queries; ++i) {
int type, pos, left, right;
uint32_t value;
fin >> type;
if (type == 0) {
fin >> pos >> value;
bit.Add(pos, value);
} else if (type == 1) {
fin >> left >> right;
fout << bit.GetSum(left, right) << "\n";
} else {
fin >> value;
fout << bit.RightBoundary(value) << "\n";
}
}
return 0;
}