Pagini recente » Cod sursa (job #109573) | Cod sursa (job #1374321) | Cod sursa (job #2232315) | Cod sursa (job #3289458) | Cod sursa (job #3267243)
// aib -> size==n
// conteaza ultimul bit de 1 al indexului
// i&-i se inverseaza toti si se pastreaza numai cel mai din dreapta bit de 1
// i=10110100, -i=01001100
// i-=(i&-i) (query) sau i+=(i&-i) (update)
// pt query tot facem operatia aia ca sa scadem cu interx
// pt update ttot facem operatitia pt a inainta in toate multimile in care se foloseste elementul x
#include <iostream>
using namespace std;
#define endl '\n'
int aib[100001], n, m, op, x, y;
void update(int ind, int x){
for (int i=ind; i<=n; i+=(i&-i)){
aib[i]+=x;
}
}
int query(int ind){
int sum=0;
for (int i=ind; i>=1; i-=(i&-i)){
sum+=aib[i];
}
return sum;
}
int main(){
freopen("aib.in", "r", stdin);
scanf("%d%d", &n, &m);
for (int i=1; i<=n; ++i){
scanf("%d", &x);
update(i, x);
}
freopen("aib.out", "w", stdout);
for (int im=0; im<m; ++im){
scanf("%d", &op);
//cout<<op<<endl;
if (op==0){
// cerinta 0
scanf("%d%d", &x, &y);
update(x, y);
} else if (op==1){
// cerinta 1
scanf("%d%d", &x, &y);
cout<<query(y)-query(x-1)<<endl;
} else {
// cerinta 2
scanf("%d", &x);
// mai eficient (cred)
int i, step;
bool ok=true;
for (step=1; step<n; step*=2){}
for(i=0; step; step/=2){
if(i+step<=n){
if(x>=aib[i+step]){
i+=step;
x-=aib[i];
if (!x){
ok=false;
break;
}
}
}
}
if (ok)cout<<"-1\n";
else cout<<i<<endl;
// ineficient
/*bool ok=true;
int st=1, dr=n;
while (st<=dr){
int mij=(st+dr)/2, q=query(mij);
if (q==x){
cout<<mij<<endl;
ok=false;
break;
} else if (x<q){
dr=mij-1;
} else {
st=mij+1;
}
}
if (ok){
cout<<"-1\n";
}*/
}
}
}