Pagini recente » Cod sursa (job #287598) | Monitorul de evaluare | Cod sursa (job #2023691) | Cod sursa (job #1296348) | Cod sursa (job #1759543)
#include <fstream>
#include <vector>
class AIB
{
public:
AIB(int);
void Insert(unsigned long long, int);
unsigned long long GetSum(int, int) const;
unsigned long long GetSum(int) const;
int GetPos(unsigned long long) const;
private:
std::vector<unsigned long long> v;
};
AIB::AIB(int n): v(n, 0) {}
void AIB::Insert(unsigned long long val, int pos)
{
if (pos > v.size())
return;
v[pos - 1] += val;
Insert(val, pos + (pos & (-pos)));
}
unsigned long long AIB::GetSum(int pos) const
{
if (pos <= 0)
return 0;
if (pos == 1)
return v[pos - 1];
return v[pos - 1] + GetSum(pos - (pos & (-pos)));
}
unsigned long long AIB::GetSum(int posA, int posB) const
{
unsigned long long a = GetSum(posA - 1), b = GetSum(posB);
return b - a;
}
int AIB::GetPos(unsigned long long a) const
{
int fst = 1;
int lst = v.size();
while (fst != lst) {
auto mid = (fst + lst) / 2;
auto sum = GetSum(mid);
if (sum < a)
fst = mid + 1;
else if (sum > a)
lst = mid - 1;
else {
if (fst != lst) {
lst = mid;
}
}
}
return fst;
}
int main()
{
int n, m;
std::ifstream f("aib.in");
std::ofstream g("aib.out");
f >> n >> m;
AIB aib(n);
for(int i = 1; i <= n; ++i){
long long x;
f >> x;
aib.Insert(x, i);
}
while (m--) {
int op;
long long a,b;
f >> op;
if (op == 0) {
f >> a >> b;
aib.Insert(b, a);
}
else
if (op == 1) {
f >> a >> b;
g << aib.GetSum(a, b) << "\n";
}
else {
f >> a;
g << aib.GetPos(a) << "\n";
}
}
f.close();
g.close();
return 0;
}