线段树求助,70分,后三个TLE
查看原帖
线段树求助,70分,后三个TLE
974512
luokes楼主2023/3/23 16:25

代码实现如下:


using namespace std;

#define NMAX 100000 	// n 的最大值 

int m,n,t;
long long int nums[NMAX+1];	 	
long long int f[NMAX*4+1]; 	// 线段树的节点,开始编号为 1,最大为 n*4+1  

// k 为当前节点的标号
// l 为当前节点区间的左边界
// r 为当前节点区间的右边界
void build_tree(int k,int l,int r)
0{
	// 如果到达了叶子节点 
	if(r == l) 
	{
		f[k] = nums[l];
		return; 
	} 
	// 其它
	int m = (l+r) >> 1; 
	build_tree(k<<1,l,m); 	    // 左孩子
	build_tree(k<<1|1,m+1,r);   // 右孩子
	f[k] = f[k<<1] + f[k<<1|1]; // 父亲的值为两孩子的和 	
}

// 修改编号为 k,区间为 [l,k]的树的 [x,y]区间 中值 
void add(int k,int l,int r,int x,int y)
{
	f[k] += (y-x+1)*t;
	// 到达了叶节点 
	if(r == l) return;
	int m = (r+l) >> 1;
	if(y <= m) add(k<<1,l,m,x,y);     	  // 如果完全坐落树的左边
	else if(x > m) add(k<<1|1,m+1,r,x,y); // 如果完全坐落树的右边
	else 								  // 两边都有
	{
		add(k<<1,l,m,x,m); 
		add(k<<1|1,m+1,r,m+1,y);
	}	
} 

// 查询编号为 k,区间为 [l,k]的树的 [x,y]区间 中值  
int calc(int k,int l,int r,int x,int y)
{
	// 如果为 K 节点
	if(l == x && r == y) return f[k];
	int m = (r+l) >> 1;
	if(y <= m) return calc(k<<1,l,m,x,y);				   // 如果完全坐落树的左边
	else if(x > m) return calc(k<<1|1,m+1,r,x,y); 		   // 如果完全坐落树的右边
	else return calc(k<<1,l,m,x,m)+calc(k<<1|1,m+1,r,m+1,y); // 两边都有 
}

int main()
{
	cin >> n >> m;
	// [1] 获取数据并进行建树
	for(int i = 1;i <= n;i++)
	{
		cin >> nums[i]; 	
	} 
	build_tree(1,1,n); 
	for(int i = 0;i < m;i++)
	{
		int op,x,y;
		cin >> op >> x >> y;
		if(op == 1)	// [2] 维护树
		{
			cin >> t;
			add(1,1,n,x,y);	
		}
		else 		// [3] 搜索树 
		{
			cout << (calc(1,1,n,x,y)) << endl;
		}
	} 

	return 0;
} 
2023/3/23 16:25
加载中...