集训final G树状数组+二分查找
需要记得开一个数组存储数据以节省查询时间。。输入输出printf,scanf是必须滴。(这一次是数据小)
#include<iostream>
using namespace std;
typedef long long int llint;
const llint MAXN=100003;
llint tree[MAXN];
llint value[MAXN];
llint lowbit(llint idx)
{
return idx & (-idx);
}
void add(llint pos, llint inc,llint n)
{
for (llint i = pos; i <= n; i += lowbit(i))
{
tree[i] += inc;
}
return ;
}
llint sum_of(llint pos)
{
llint sum = 0;
for (llint i = pos; i > 0; i -= lowbit(i))
{
sum += tree[i];
}
return sum;
}
int main()
{
llint n;
while(cin>>n)
{
llint i;
memset(tree,0,sizeof(tree));
memset(value,0,sizeof(value));
for(i=1;i<=n;i++)
{
scanf("%I64d",&value[i]);
add(i,value[i],n);
}
llint m;
scanf("%I64d",&m);
while(m--)
{
char s[10];
scanf("%s",s);
if(s[0]=='C')
{
llint a,b;
scanf("%I64d%I64d",&a,&b);
add(a,b-value[a],n);
value[a]=b;
}else if(s[0]=='Q')
{
llint pos;
llint l,h,m;
l=1;
h=n;
//cout<<n<<endl;
bool tag=1;
scanf("%I64d",&pos);
//printf("%I64d|%I64d|%I64d\n",l,m,h);
while(h>l&&(h-l)!=1)
{
m=(l+h)/2;
// cout<<l<<"|"<<h;
//printf("%I64d|%I64d|%I64d\n",l,m,h);
llint sm=sum_of(m);
if(sm==pos)
{
while(value[m]==0&&m!=0)
{
m--;
}
cout<<m<<endl;
tag=0;
break;
}else if(sm>pos)
{
h=m;
}else
{
l=m;
}
}
if(tag)
{
if(sum_of(l)>=pos)
{
while(value[l]==0&&l!=0)
{
l--;
}
cout<<l<<endl;
}else
{
while(value[h]==0&&h!=0)
{
h--;
}
cout<<h<<endl;
}
}
}
}
}
return 0;
}
本博客(http://www.cnblogs.com/cj695/)未标明转载的内容均为本站原创,非商业用途转载时请署名(77695)并注明来源(http://www.cnblogs.com/cj695/)。商业用途请联系作者(77695) QQ:646710030。作者(77695)保留本博客所有内容的一切权利。
独立博客:http://nfeng.cc/
独立博客:http://nfeng.cc/

浙公网安备 33010602011771号