直接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; }