Pagini recente » Cod sursa (job #2282261) | Cod sursa (job #43168) | Cod sursa (job #2734428) | Cod sursa (job #1707551) | Cod sursa (job #2646872)
#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define debug(x) cerr << #x << " = " << x << "\n"
#define all(x) (x).begin(),(x).end()
#define len(x) (x).length()
#define sqr(x) (x) * (x)
using ull = unsigned long long;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; /// Ordered Set : find_by_order, order_of_key
template <typename T>
ostream& operator<<(ostream &os, const vector<T> &v) { os << '{'; string sep; for (const auto &x : v) os << sep << x, sep = ", "; return os << '}'; }
template <typename A, typename B>
ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
const int INF = INT_MAX;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;
const double PI = acos(-1);
ll t, n;
/**
* Author: neal
* Data structure: Fenwick Tree (Binary Index Tree - BIT)
*/
template<typename T>
struct fenwick_tree {
int tree_n = 0;
T tree_sum = 0;
vector<T> tree;
fenwick_tree(int n = -1) {
if (n >= 0)
init(n);
}
void init(int n) {
tree_n = n;
tree_sum = 0;
tree.assign(tree_n + 1, 0);
}
// O(n) initialization of the Fenwick tree.
template<typename T_array>
void build(const T_array &initial) {
assert(int(initial.size()) == tree_n);
tree_sum = 0;
for (int i = 1; i <= tree_n; i++) {
tree[i] = initial[i - 1];
tree_sum += initial[i - 1];
for (int k = (i & -i) >> 1; k > 0; k >>= 1)
tree[i] += tree[i - k];
}
}
// index is in [0, tree_n).
void update(int index, const T &change) {
assert(0 <= index && index < tree_n);
tree_sum += change;
for (int i = index + 1; i <= tree_n; i += i & -i)
tree[i] += change;
}
// Returns the sum of the range [0, count).
T query(int count) const {
assert(count <= tree_n);
T sum = 0;
for (int i = count; i > 0; i -= i & -i)
sum += tree[i];
return sum;
}
// Returns the sum of the range [start, tree_n).
T query_suffix(int start) const {
return tree_sum - query(start);
}
// Returns the sum of the range [a, b).
T query(int a, int b) const {
return query(b) - query(a);
}
// Returns the element at index a in O(1) amortized across every index. Equivalent to query(a, a + 1).
T get(int a) const {
assert(0 <= a && a < tree_n);
int above = a + 1;
T sum = tree[above];
above -= above & -above;
while (a != above) {
sum -= tree[a];
a -= a & -a;
}
return sum;
}
bool set(int index, T value) {
assert(0 <= index && index < tree_n);
T current = get(index);
if (current == value)
return false;
update(index, value - current);
return true;
}
// Returns the largest p in `[0, tree_n]` such that `query(p) <= sum`. Returns -1 if no such p exists (`sum < 0`).
// Can be used as an ordered set/multiset on indices in `[0, tree_n)` by using the tree as a 0/1 or frequency array:
// `set(index, 1)` is equivalent to insert(index). `update(index, +1)` is equivalent to multiset.insert(index).
// `set(index, 0)` or `update(index, -1)` are equivalent to erase(index).
// `get(index)` provides whether index is present or not, or the count of index (if multiset).
// `query(index)` provides the count of elements < index.
// `find_last_prefix(k)` finds the k-th smallest element (0-indexed). Returns `tree_n` for `sum >= set.size()`.
int find_last_prefix(T sum) const {
if (sum < 0)
return -1;
int prefix = 0;
for (int k = 31 - __builtin_clz(tree_n); k >= 0; k--)
if (prefix + (1 << k) <= tree_n && tree[prefix + (1 << k)] <= sum) {
prefix += 1 << k;
sum -= tree[prefix];
}
if (sum) return -1;
return prefix;
}
};
int main(){
ios_base::sync_with_stdio(0); cin.tie(0);// cout.tie(0);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
ifstream cin("aib.in");
ofstream cout("aib.out");
int m, a, b, c;
cin >> n >> m;
fenwick_tree<int> fw(n);
for (int i = 0; i < n; i++) {
cin >> a;
fw.update(i, a);
}
while (m--) {
cin >> c;
if (c == 0) {
cin >> a >> b;
fw.update(a - 1, b);
} else if (c == 1) {
cin >> a >> b;
cout << fw.query(a - 1, b) << "\n";
} else {
cin >> a;
cout << fw.find_last_prefix(a) << "\n";
}
}
return 0;
}