p1247

看到n,m<=100000可以想到这是一个考高级数据结构的题,这个区间修改区间查询让我想到了线段树和树状数组。

然而看了一遍题后眉头一皱,发现并不简单。

它要求输出区间上炸弹种类数,那么维护区间和也不对,维护区间最大值也不对,看来不能直接套模板了。

这个时候需要重新综合考虑修改和查询的内容了。经过思考可以想到离散化的方法,把区间修改改成单点修改,区间查询即为求区间∑。

那么就可以写一个树状数组了, 毕竟代码好写很多很多很多。

对于每个修改把原数组左右端点所在位置++(注意开两个数组),经过一系列复杂的画图推演和模拟可以得到询问的ans=炸弹总数-sumzuo[r]-you[l-1];(具体推导在我英语卷上明天再来补)

本题可A。

int i,t,tl,tr;
int m,n;
int zuo[1000010],you[1000010];
int lowbit(int x)
{
    return x&(-x);
}
void addzuo(int p,int k)
{
    while(p<=n)
    {
        zuo[p]+=k;
        p+=lowbit(p);
    }
}
void addyou(int p,int k)
{
    while(p<=n)
    {
        you[p]+=k;
        p+=lowbit(p);
    }
}
int sumzuo(int x)
{
    int ans=0;
    while(x)
    {
        ans+=zuo[x];
        x-=lowbit(x);
    }
    return ans;
}
int sumyou(int x)
{
    int ans=0;
    while(x)
    {
        ans+=you[x];
        x-=lowbit(x);
    }
    return ans;
}
int main()
{

    cin>>n>>m;
    
    for(i=1;i<=m;i++)
    {
        cin>>t>>tl>>tr;
        if(t==1)
        {
            addzuo(tl,1);
            addyou(tr,1);
        }
        else
            
            cout<<sumzuo(tr)-sumyou(tl-1)<<endl;
    }
}

还好没有卡tl=1或等0的数据…………

猜你喜欢

转载自www.cnblogs.com/qywyt/p/9623261.html