直接for(int i=x;i<=n;i+=x)add(i,y);最坏是o(n^m)=1e10,会爆掉
所以需要用个lazy[]进行分块统计小于sqrt(n)复杂度较大的那一部分y,
最后在算range_sum(x,y)的时候加上[x,y]中lazy[]数组的贡献
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;
ll tree[100050],lazy[100050],n,m,ans;
ll lowbit(ll x)
{
return x&-x;
}
void add(ll i,ll x)
{
while(i<=n)
{
tree[i]+=x;
i+=lowbit(i);
}
}
ll sum(ll i)
{
ll res=0;
while(i>0)
{
res+=tree[i];
i-=lowbit(i);
}
return res;
}
ll range_sum(ll l,ll r)
{
return sum(r)-sum(l-1);
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
cin>>n>>m;
while(m--)
{
ll f,x,y;
cin>>f>>x>>y;
if(f==1){
if(x<=sqrt(n)){
lazy[x]+=y;
}
else{
for(ll i=x;i<=n;i+=x)
add(i,y);
}
}
else if(f==2) {
ans=range_sum(x,y);
for(ll i=1;i<=sqrt(n);i++)
ans+=(y/i-(x-1)/i)*lazy[i];
cout<<ans<<endl;
}
}
return 0;
}
京公网安备 11010502036488号