集训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/
原文地址:https://www.cnblogs.com/cj695/p/2623278.html