Pagini recente » Cod sursa (job #1138941) | Cod sursa (job #2219919) | Cod sursa (job #1810617) | Cod sursa (job #827248) | Cod sursa (job #1591248)
#include <bits/stdc++.h>
using namespace std;
ifstream in("aib.in");
ofstream out("aib.out");
#define MAX 100008
int n,m,arb[MAX],a,b,x,k;
void update(int poz, int val)
{
int c=0;
while(poz<=n)
{
arb[poz]+=val;
while((poz&(1<<c))==0)c++;
//cautam primul bit care nu e egal cu 0 de la cel mai nesemnificativ
//si il adaugam la poz.
//https://www.youtube.com/watch?v=CWDQJGaN1gY
//ex : 3->4->8->16...
poz=poz+(1<<c);
c=c+1;
}
}
int query(int poz)
{
int c=0,s=0;
while(poz>0)
{
s=s+arb[poz];
while((poz&(1<<c))==0)c++;
poz=poz-(1<<c);
c=c+1;
}
return s;
/*ex:
15= 1111
14= 1110 (tatal lui 15)
12=1100(tatal lui 14)
8=1000(tatal lui 12)
0=0000(tatal lui 8)
:)
*/
//pozitiile impare nu au fii
}
int caut(int sum)
{
int pas=1;
while(pas<n)
pas=pas<<1;
//cea mai mare putere a lui 2 mai mica decat n
for(int i=0;pas;pas=pas>>1)
{
//cat timp pas mai mare decat 0, pas devine pas/2
if(i+pas<=n)
{
if(sum>=arb[i+pas])
{
sum=sum-arb[i+pas];
i=i+pas;
if(sum==0)return i;
// ca si cum am cauta bitii de 1 (mai intai gasim baza si pe urma mergem in jos pe arbore :) )
}
}
}
return -1;
}
int main()
{ in>>n>>m;
for(int i=1;i<=n;i++)
{
in>>x;
update(i,x);
//pe pozitia i (val.=0) se aduna val. b
}
while(m--)
{
in>>k;
if(k==0)
{
in>>a>>b;
update(a,b);
//pe pozitia a se aduna val. b
}
if(k==1)
{
in>>a>>b;
out<<query(b)-query(a-1)<<'\n';
//suma elementelor de la 0 pana la pozitia b - suma el. de la 0 la a-1 (suma el. de la a la b)
}
if(k==2)
{
in>>a;
out<<caut(a)<<'\n';
// pozitia minima k a.i. suma primilor k termeni sa fie a
}
}
return 0;
}