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

    线段树模板

    单点修改 区间查询模板

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    
    using namespace std;
    const int N = 100010;
    
    int n , m ;
    int w[N];
    
    struct node{
    	int l , r , sum;
    }tr[N * 4];
    
    
    
    void build(int u,int l, int r)
    {
    	if(l == r){
    		tr[u].l = l;tr[u].r = r;
    		tr[u].sum = w[r];
    	}
    	else{
    		tr[u].l = l;tr[u].r = r;
    		int mid = l + r >> 1;
    		build(u << 1,l ,mid);
    		build(u << 1 | 1,mid + 1, r);
    		tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
    	}
    }
    
    int query(int u,int l,int r)
    {
    	if(tr[u].l >= l && tr[u].r <= r)return tr[u].sum;
    	int mid = tr[u].l + tr[u].r >> 1;
    	int sum = 0;
    	if(l <= mid)sum = query(u << 1, l , r);
    	if(r > mid) sum += query(u << 1 | 1, l , r);
    	return sum;
    }
    
    void modify(int u,int x,int v)
    {
    	if(tr[u].l == tr[u].r)tr[u].sum += v;
    	else{
    		int mid = tr[u].l + tr[u].r >> 1;
    		if(x <= mid)modify(u << 1, x , v);
    		else modify(u << 1 | 1,x , v);
    		tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
    	}
    }
    
    int main()
    {
    	cin >> n >> m;
    	// 权值数组必须从1 开始 
    	for(int i = 1;i <= n ;i ++)
    	{
    		scanf("%d",&w[i]);
    	}
    	
    	build(1 , 1 , n);
    	
    	for(int i = 0;i < m ;i ++)
    	{
    		int c, x , y;
    		cin >> c >> x >> y;
    		if(c == 0){
    			cout << query(1 , x , y) << endl; 
    		}else{
    			modify(1 , x, y);
    		}
    	}
    	return 0;
    }
    
    

    区间修改 区间查询

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    
    using namespace std;
    const int N = 100010;
    
    typedef long long ll;
    
    ll n , m ;
    ll w[N];
    
    struct node{
    	ll l , r , sum , lazy;
    }tr[N * 4];
    
    
    void add(int u,int v)
    {
    	tr[u].lazy += v;
    	tr[u].sum += (tr[u].r - tr[u].l + 1) * v;
    	return;
    }
    
    void pushdown(int u,int l,int r)
    {
    	if(tr[u].lazy == 0)return ;
    	add(u << 1,tr[u].lazy); //下传左子树 
    	add(u << 1 | 1,tr[u].lazy);//下传右子树 
    	tr[u].lazy = 0; //取消标记 
    }
    
    
    void build(int u,int l, int r)
    {
    	if(l == r){
    		tr[u].l = l;tr[u].r = r;
    		tr[u].sum = w[r];
    	}
    	else{
    		tr[u].l = l;tr[u].r = r;
    		int mid = l + r >> 1;
    		build(u << 1,l ,mid);
    		build(u << 1 | 1,mid + 1, r);
    		tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
    	}
    }
    
    ll query(int u,int l,int r)
    {
    	if(tr[u].l >= l && tr[u].r <= r)return tr[u].sum;
    	int mid = tr[u].l + tr[u].r >> 1;
    	ll sum = 0;
    	pushdown(u , l , r);
    	if(l <= mid)sum = query(u << 1, l , r);
    	if(r > mid) sum += query(u << 1 | 1, l , r);
    	return sum;
    }
    
    void modify(int u,int l, int r,ll v)
    {
    	if(tr[u].l >= l && tr[u].r <= r)
    	{
    		return add(u,v);
    	}
    	int mid = tr[u].l + tr[u].r >> 1;
    	pushdown(u , l , r);
    	if(l <= mid)modify(u << 1,l , r , v) ;
    	if(r > mid) modify(u << 1 | 1,l , r, v);
    	tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
    } 
    
    int main()
    {
    	cin >> n >> m;
    	// 权值数组必须从1 开始 
    	for(int i = 1;i <= n ;i ++)
    	{
    		scanf("%d",&w[i]);
    	} 
    	build(1 , 1 , n); 
    	int f , x , y , k;
    	while(m--)
    	{
    		cin >> f;
    		if(f == 1)
    		{
    			cin >> x >> y >> k;
    			modify(1,x , y , k);
    		}else{
    			cin >> x >> y;
    			cout << query(1,x,y) << endl;
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    洛谷 P2234 [HNOI2002]营业额统计
    洛谷p3146&p3147
    洛谷 p1439 最长公共子序列
    搜索
    一步一步分析Caliburn.Micro(二:绑定执行方法Message现学现卖之自定命令)
    一步一步分析Caliburn.Micro(一:绑定执行方法Message)
    整理的C# 字符串类
    不用ADOX.CatalogClass创建Access数据库文件
    取远程网页数据 WebClient,HttpWebRequest
    C# LinQ 与 ADO.NET
  • 原文地址:https://www.cnblogs.com/wlw-x/p/12536899.html
Copyright © 2011-2022 走看看