zoukankan      html  css  js  c++  java
  • 线段树模板

    超高校级的毒瘤码风

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1000010; 
    int n,m;
    ll arr[N];
    ll tree[N<<2]={0};//四倍于原数组 
    ll lazy[N<<2];//lazy tag
    
    /*懒标记下传函数*/
    inline void func(ll node,ll l,ll r,ll k)
    {
    	lazy[node]=lazy[node]+k;
    	tree[node]=tree[node]+k*(r-l+1);//区间统一改变,所以要加上区间总变化量,下同 
    }
    inline void push_down(int node,int l,int r)
    {
    	if(!lazy[node]) return ;
    	ll mid=(l+r)>>1;
    	int left_node=node<<1;
    	int right_node=(node<<1)|1;
    	if(lazy[node]==0) return ;
    	func(left_node,l,mid,lazy[node]);
    	func(right_node,mid+1,r,lazy[node]);
    	lazy[node]=0;//tag推掉了,归零 
    }
    
    /*建树函数*/
    void build_tree(int node/*节点编号*/,int start/*区间起点*/,int end/*区间终点*/) 
    {
    	lazy[node]=0;
    	if(start==end)//递归出口:当区间无法继续细分 
    	{
    		tree[node]=arr[start];
    		return ;
    	}
    	int mid=(start+end)>>1;
    	int left_node=node<<1;
    	int right_node=(node<<1)|1;
    	build_tree(left_node,start,mid);
    	build_tree(right_node,mid+1,end);
    	
    	tree[node]=tree[left_node]+tree[right_node];//维护线段树 
    }
    
    /*区间修改函数*/
    void update_itv(int node,int start,int end,int l/*修改区间左端点*/,int r/*修改区间右端点*/,ll vol/*操作数(加上的数)*/)
    {
    	if(l<=start&&end<=r)
    	{
    //		cout<<start<<'#'<<end<<endl;
    		tree[node]+=vol*(end-start+1);
    		lazy[node]+=vol;//打懒标记 
    		return ;
    	}
    	push_down(node,start,end);
    	/*需要向下推 懒标记*/
    	int mid=start+end>>1;
    	int left_node=node*2;
    	int right_node=(node*2)+1;
    	if(l<=mid) update_itv(left_node,start,mid,l,r,vol);
    	if(r>mid) update_itv(right_node,mid+1,end,l,r,vol);
    	tree[node]=tree[left_node]+tree[right_node];//维护 
    }
    
    /*区间查询函数*/
    ll query(int node,int start,int end,int l/*查询区间起点*/,int r/*查询区间终点*/)
    {
    	if(end<l||start>r) 
    		return 0;//不在计算范围内
    	if(l<=start&&end<=r)
    		return tree[node];//当前区间被包含 
    	int mid=start+end>>1;
    	push_down(node,start,end);//推lazy 
    	int left_node=node*2;
    	int right_node=(node*2)|1;
    	ll sum_left=query(left_node,start,mid,l,r);
    	ll sum_right=query(right_node,mid+1,end,l,r);
    	
    	return sum_left+sum_right;//维护 
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%lld",&arr[i]);
    	}
    	build_tree(1,1,n);
    	for(int i=1;i<=m;i++)
    	{
    		int k,x,y,z;
    		scanf("%d",&k);
    		if(k==1)
    		{
    			scanf("%d%d%d",&x,&y,&z);
    			if(x>y) swap(x,y);
    			update_itv(1,1,n,x,y,z); 
    //			cout<<
    		}
    		else 
    		{
    			scanf("%d%d",&x,&y);
    			if(x>y) swap(x,y);
    			printf("%lld
    ",query(1,1,n,x,y));
    		}
    	}
    }
    
    
  • 相关阅读:
    树套树
    Luogu P2839 [国家集训队]middle
    苟随笔
    BJOI2014 大融合
    轻量树上问题选做
    sb的斜率优化笔记
    CDialogEx::OnPaint()的问题,或者为什么在对话框程序的OnPaint中绘图无效的问题
    VC6的工程转到VC2010或更高版本出现fatal error C1189编译错误的解决方法
    C语言实现的反转字符串
    在终端输入npm run serve时出现npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! test_vue_0613@1.0.0 dev: 错误的解决方法
  • 原文地址:https://www.cnblogs.com/IzayoiMiku/p/13581611.html
Copyright © 2011-2022 走看看