1 条题解

  • 0
    @ 2025-8-24 22:05:29

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar gwx123456
    我们奔跑中编制美梦 看着世间的欢喜流过.

    搬运于2025-08-24 22:05:29,当前版本为作者最后更新于2019-06-26 22:22:40,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    树状数组+差分 虽然也可以用线段树

    首先,你需要普及一些前缀知识:树状数组和差分

    如果你没学过差分,就点这里

    如果你没学过树状数组,就点这里

    注:树状数组虽然只有一道例题,但也详细讲解了树状数组

    相信,你看完上面两个链接后就明白代码怎么写了吧。

    上代码:

    #include <bits/stdc++.h>
    using namespace std;
    int n,a[10000001],c[10000001],m;
    int lowbit(int i){
        return i&(-i);
    }
    int getSum(int x){//求和
        int sum=0;
        for(int i=x;i>0;i-=lowbit(i))//树状数组的前缀和
            sum+=c[i];
        return sum;
    }
    void modify(int x,int delta){//改变数据
        for(int i=x;i<=n;i+=lowbit(i)) //因为前缀和是一个一个推的,所以一个儿子节点改变了,所有父亲节点也要改变 
            c[i]+=delta;
    }
    int main(){
        cin>>n;
        cin>>m;
        for(int i=1;i<=m;i++){
            int a,b,c;
            cin>>c;
            if(c==1){
                cin>>a;
                cout<<getSum(a)<<endl;//树状数组前缀和得到单点查询
            }
            else {
                cin>>a>>b;
                modify(a,1);//差分,因为a~b加1就相当于左边的加1右边的减1(差分博客里详细讲解了差分用法)
                modify(b+1,-1);
            }
        }
        return 0;
    }
    
    • 1

    信息

    ID
    3926
    时间
    1000ms
    内存
    125MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者