社区讨论

暴力st表通过本题

P3372【模板】线段树 1参与者 3已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mhj2yo5d
此快照首次捕获于
2025/11/03 19:52
4 个月前
此快照最后确认于
2025/11/03 19:52
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct node{
	ll l,r,k;
};
ll n,q,a[100010],logv[100010],st[20][100010],block,diff[100010];
vector <node> lazy;
void build(){
	for (ll i=1;i<=n;i++)  st[0][i]=a[i];
    for (ll j=1;(1<<j)<=n;j++){
        ll len=1<<j,mid=len>>1;
        for (int i=1;i+len-1<=n;i++){
            st[j][i]=st[j-1][i]+st[j-1][i+mid];
        }
    }
}
void update(ll l,ll r,ll k){
	lazy.push_back({l,r,k});
	if (lazy.size()>block){
		memset(diff,0,sizeof(diff));
		for (auto p:lazy)  diff[p.l]+=p.k,diff[p.r+1]-=p.k;
		for (int i=1;i<=n;i++){
			diff[i]+=diff[i-1];
			a[i]+=diff[i];	
		}
		lazy.clear();
		build();
	}
}
ll query(ll l,ll r){
	ll res=0,len=r-l+1,lll=l;
    for (ll j=logv[len];j>=0;j--)
        if (1<<j<=len)  res+=st[j][lll],lll+=1<<j,len-=1<<j;
    for (auto p:lazy){
    	ll L=max(l,p.l),R=min(r,p.r);
    	if (L<=R)  res+=(ll)(p.k*(R-L+1));
	}
	return res;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>q;
	for (int i=1;i<=n;i++)  cin>>a[i];
	logv[1]=0;
    for (ll i=2;i<=n;i++){
        logv[i]=logv[i/2]+1;
    }
    build();
    block=sqrt(n);
    while (q--){
    	ll op,x,y,k;
    	cin>>op; 
    	if (op==1){
    		cin>>x>>y>>k;
    		update(x,y,k);
		}else{
			cin>>x>>y;
			cout<<query(x,y)<<"\n";
		}
	}
	return 0;
} 
求优化+时间复杂度分析

回复

7 条回复,欢迎继续交流。

正在加载回复...