我的线段树常数大吗
  • 板块学术版
  • 楼主wo_hen_la
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/10/20 17:45
  • 上次更新2024/10/20 19:42:43
查看原帖
我的线段树常数大吗
794701
wo_hen_la楼主2024/10/20 17:45

为什么有些题我用这个跟用 超级树状数组 的时间差很多,差1s

#include <iostream>
#define int long long
#define N 100005 
using namespace std;
int a[N];
struct node
{
	int num,l,r,lz;
}tr[N*4];
void up(int k)
{
	tr[k].num=tr[k<<1].num+tr[k<<1|1].num;
}
void build(int k,int ll,int rr)
{
	tr[k]={0,ll,rr,0};
	if(ll==rr){
		tr[k].num=a[ll];
		return;
	}
	int mid=ll+rr>>1;
	build(k<<1,ll,mid);
	build(k<<1|1,mid+1,rr);
	up(k);
}
void down(int k)
{
	tr[k<<1].lz+=tr[k].lz;
	tr[k<<1|1].lz+=tr[k].lz;
	tr[k<<1].num+=(tr[k<<1].r-tr[k<<1].l+1)*tr[k].lz;
	tr[k<<1|1].num+=(tr[k<<1|1].r-tr[k<<1|1].l+1)*tr[k].lz;
	tr[k].lz=0;
}
void modify(int k,int ll,int rr,int val)
{
	if(tr[k].l>=ll && tr[k].r<=rr){
		tr[k].num+=(tr[k].r-tr[k].l+1)*val;
		tr[k].lz+=val;
		return;
	}
	if(tr[k].lz) down(k);
	int mid=tr[k].l+tr[k].r>>1;
	if(ll<=mid)	modify(k<<1,ll,rr,val);
	if(rr>mid) modify(k<<1|1,ll,rr,val);
	up(k);
}
int query(int k,int ll,int rr)
{
	if(tr[k].l>=ll && tr[k].r<=rr) return tr[k].num;
	if(tr[k].lz) down(k);
	int mid=tr[k].l+tr[k].r>>1,cnt=0;
	if(ll<=mid) cnt+=query(k<<1,ll,rr);
	if(rr>mid) cnt+=query(k<<1|1,ll,rr);
	return cnt;
}
main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	while(m--){
		int c,x,y,k;
		cin>>c>>x>>y;
		if(c==1){
			cin>>k;
			modify(1,x,y,k);
		}
		if(c==2) cout<<query(1,x,y)<<"\n";
	}
	return 0;
}
2024/10/20 17:45
加载中...