集训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/