/* FILE: dynArray.cpp last change: 23-Jan-2013 author: Romeo Rizzi * the solver for problem dynArray */ #define NDEBUG // NDEBUG definita nella versione che consegno #include #ifndef NDEBUG # include // uso di cin e cout non consentito in versione finale #endif #include using namespace std; // ogni numero naturale puo' essere rappresentato in modo unico come somma di potenze di due distinte. La sequente funzione ritorna la piu' piccola di tali potenze: int LSOne(int n) { return (n) & (-n); } // Least Significant One, sfrutta le proprieta' della rappresentazione in complemento a 2 e una bit manipulation. // l'array A del testo del problema e' indicizzato da 1 a n. Nella struttura dati che impiegheremo l'indicizzazione da 1 viene di fatto comoda. int n; const int MAX_N = 1000000; #ifndef NDEBUG int A[MAX_N +1]; // l'array A del problema. Essendo esso ridondato nella struttura ft qui impiegata per risolvere nel modo piu' agevole il problema, non e' di fatto necessario. Lo teniamo qui nel sorgente per dare leggibilita' al codice e per consentire facile self-debugging. int slowSumOverA(int posA, int posB) { // only for checking int sum = 0; while( posA <= posB ) sum += A[posA++]; return sum; } #endif int m; // numero di istruzioni in input // a Fenwick Tree -also known as Binary Indexed Tree (BIT) int ft[MAX_N +1]; //ft[pos] is the sum of the entries in A[pos-LSOne(pos)+1,pos] int sumFromPos1toPos(int pos) { if( pos <= 0 ) return 0; return ft[pos] + sumFromPos1toPos(pos-LSOne(pos)); } void add(int pos, int val) { // A picture for A[1..9] might help: while( pos <= n ) { // XXXXXXXX <-- ft[8] ft[pos] += val; // XXXX <-- ft[4] pos += LSOne(pos); // XX XX <-- ft[2], ft[6] } // X X X X X <-- ft[1],ft[3],ft[5],ft[7],ft[9] } // 123456789 int sum(int posA, int posB) { return sumFromPos1toPos(posB) - sumFromPos1toPos(posA-1); } int main() { ifstream fin("input.txt"); assert( fin ); fin >> n >> m; for(int i = 1; i <= n; i++) { ft[i] = 0; assert( (A[i] = 0) || true ); } ofstream fout("output.txt"); assert( fout ); for(int i = 0; i < m; i++) { int key, a, b; fin >> key; if( key ) { fin >> a; add(a, key); assert( (A[a] += key) || true ); } else { fin >> a >> b; key = sum(a, b); assert( key == slowSumOverA(a,b) ); fout << key << " " << endl; } } fin.close(); fout.close(); return 0; }