华华开始学信息学

华华开始学信息学

https://ac.nowcoder.com/acm/problem/23054

当d<=sqrt(n)时 直接暴力修改树状数组的值会使复杂度退化到O(n²)
所以这里要用到分块的思想,修改lazy标记
lazy[i]表示i的倍数的位置中所有的数组成的一个块,查询时l到r对应的lazy,这中间有r/i-(l-1)/i个数,乘以lazy[i]就是分块记录的答案
跟树状数组直接记录的答案相加就是最终的答案

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
const int N=100010;
int c[N];
int lazy[1000];
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int k)
{
    while(x<=n)
    {
        c[x]+=k;
        x+=lowbit(x);
    }
}
int getsum(int x)
{
    int ans=0;
    while(x>=1)
    {
        ans+=c[x];
        x-=lowbit(x);
    }
    return ans;
}
signed main()
{
    scanf("%lld%lld",&n,&m);
    while(m--)
    {
        int op;
        scanf("%lld",&op);
        if(op==1)
        {
            int d,k;
            scanf("%lld%lld",&d,&k);
            if(d<=sqrt(n))
            {
                lazy[d]+=k;
            }
            else
            {
                for(int i=d;i<=n;i+=d)
                {
                    update(i,k);
                }
            }
        }
        else
        {
            int l,r;
            scanf("%lld%lld",&l,&r);
            int ans=getsum(r)-getsum(l-1);
            for(int i=1;i<=sqrt(n);i++)
                ans+=((r/i)-(l-1)/i)*lazy[i];
            printf("%lld\n",ans);
        }
    }
}
全部评论

相关推荐

程序员牛肉:这一眼假啊,基本上都是骗人的,不然就涉及到职位贪腐了,就像之前华为的OD事件,看你运气好不好了
点赞 评论 收藏
分享
大方的大熊猫准备进厂:1.教育背景:你希望从事什么专业的工作你的主修课就是什么;成绩优秀是你应该做的,没什么可描述的,成绩不优秀也许人家在大学忙着创业呢?(成绩优秀不一定是好事,只能说明多元化的大学你上成了高中,没有真正上明白大学,反而体现了你死板,不爱社交,没有别的突出能力) 2.实践经历:你想表达的意思没有说清楚。你是说你会个性化服务,还是你有实习经历。如果没有带来,经济收益,表彰,更好的发展前景,那你还不如说说提升了自己哪些技能。你说有人给你送锦旗我都能明白你优秀,但是你说你会xxxx,你说这话谁信,证据呢。 3.入伍经历:你描述的就是你的工作职责或者你应该做的,并没有体现出来你把这个事情做好了,而且入伍经历并不能证明你能干好你要应聘的工作,不如只写经历其余所有内容都不写。 4.荣誉技能:重点突出一下,但不要过多描述,这些荣誉的含金量懂得都懂。 重点:你要应聘什么工作(具体岗位,实习生不具体),你的期望薪资
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务