Pagini recente » Cod sursa (job #2092061) | Cod sursa (job #2622227) | Cod sursa (job #1131865) | Cod sursa (job #2640155) | Cod sursa (job #2614996)
#define MAX_N 100000
#define LOG_MAX_N 16
#define FTH(x) (x >> 1)
#define LFT_SON(x) (x << 1)
#define RIG_SON(x) (LFT_SON(x) + 1)
#include <fstream>
using namespace std;
ifstream fin("aib.in");
ofstream fout("aib.out");
struct nodeinfo
{
int a, b, sum;
};
int n, m, A[MAX_N + 1], I[MAX_N + 1];
nodeinfo G[1 << (LOG_MAX_N + 2)];
void ConstructTree(int node, int a, int b);
void Update(int index, int val);
int SumRange(int a, int b);
void Query(int node, int a, int b, int& sum);
int MinK(int sum);
void QueryK(int node, int sum, int& k);
int main()
{
fin >> n >> m;
for (int i = 1; i <= n; ++i)
{
fin >> A[i];
}
ConstructTree(1, 1, n);
for (int i = 1, c, a, b; i <= m; ++i)
{
fin >> c;
if (c == 0)
{
fin >> a >> b;
Update(a, b);
}
if (c == 1)
{
fin >> a >> b;
fout << SumRange(a, b) << '\n';
}
if (c == 2)
{
fin >> a;
fout << MinK(a) << '\n';
}
}
fin.close();
fout.close();
return 0;
}
void ConstructTree(int node, int a, int b)
{
G[node] = { a, b };
if (a == b)
{
I[a] = node;
G[node].sum = A[a];
}
else
{
const int mid = (a + b) / 2;
ConstructTree(LFT_SON(node), a, mid);
ConstructTree(RIG_SON(node), mid + 1, b);
G[node].sum = G[LFT_SON(node)].sum + G[RIG_SON(node)].sum;
}
}
void Update(int index, int val)
{
int node = I[index];
G[node].sum += val;
node = FTH(node);
int sum_old;
while (node != 0)
{
sum_old = G[node].sum;
G[node].sum = G[LFT_SON(node)].sum + G[RIG_SON(node)].sum;
node = (sum_old != G[node].sum) ? FTH(node) : 0;
}
}
int SumRange(int a, int b)
{
int sum = 0;
Query(I[a], a, b, sum);
return sum;
}
void Query(int node, int a, int b, int& sum)
{
while (true)
{
if (G[node].b < b)
{
if (G[node].a < a)
{
sum += G[RIG_SON(node)].sum;
}
node = FTH(node);
}
else
{
if (G[node].a < a)
{
node = RIG_SON(node);
}
else
{
if (G[node].b == b)
{
sum += G[node].sum;
return;
}
if (G[LFT_SON(node)].b < b)
{
sum += G[LFT_SON(node)].sum;
node = RIG_SON(node);
}
else
{
node = LFT_SON(node);
}
}
}
}
}
int MinK(int sum)
{
int k;
QueryK(I[1], sum, k);
return k;
}
void QueryK(int node, int sum, int& k)
{
while (true)
{
if (G[node].sum < sum)
{
if (node != 1)
{
node = FTH(node);
}
else
{
k = -1;
return;
}
}
else
{
if (G[node].sum == sum)
{
k = G[node].b;
return;
}
if (G[node].a != G[node].b)
{
const int sum_lft = G[node].sum - G[RIG_SON(node)].sum;
if (sum_lft >= sum)
{
node = LFT_SON(node);
}
else
{
sum -= sum_lft;
node = RIG_SON(node);
}
}
else
{
k = -1;
return;
}
}
}
}