Cod sursa(job #697709)

Utilizator Robert29FMI Tilica Robert Robert29 Data 29 februarie 2012 10:39:50
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.34 kb
#include<stdio.h>
FILE*f=fopen("aib.in","r");
FILE*g=fopen("aib.out","w");
int n,m,a,b,x,w[200001],v[200001];

int query(int b)
{
	int x=0;
	
	while(b){
		x+=w[b];
		b-=(b^(b-1))&b;
	}
	
	return x;
}
int main() {
	fscanf(f,"%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		fscanf(f,"%d",&v[i]);
	for(int i=1;i<=n;++i){
		int y=(i^(i-1))&i;
		for(int j=i-y+1;j<=i;++j)
			w[i]+=v[j];
	}
	for(int i=1;i<=m;++i){
		fscanf(f,"%d",&x);
		if(!x){
			fscanf(f,"%d%d",&a,&b);
			while(a<=n){
				w[a]+=b;
				a+=(a^(a-1))&a;
			}
		}else if(x==1){
			fscanf(f,"%d%d",&a,&b);
			a--;
			int x=0;
			int y=0;
			while(b){
				x+=w[b];
				b-=(b^(b-1))&b;
			}
			while(a){
				y+=w[a];
				a-=(a^(a-1))&a;
			}
			fprintf(g,"%d\n",x-y);
		}else{
			fscanf(f,"%d",&a);
			b=1;
			while(w[b]<a&&b<=n)
				b*=2;
			int aa;
			int st=0;
			int dr=n+1;
			int mm=(st+dr)/2;
			int pos=300000;
			while(mm)
			{
				mm=(st+dr)>>1;
				aa=query(mm);
				if(aa>a)
				{
					if(dr>mm)
						dr=mm;
					--mm;
				}
				else if(aa==a)
				{
					if(pos>mm)
						pos=mm;
					dr=mm;
					--mm;
				}
				else
				{
					if(st<mm)
						st=mm;
					aa+=w[mm];
					++mm;
				}
					
				if(mm>=dr)
					break;
				if(mm<=st)
					break;
				
			}
			if(pos>n)
				fprintf(g,"-1\n");
			else
				fprintf(g,"%d\n",pos);
		}
		
	}
	
	fclose(g);
	fclose(f);
	return 0;
}