• 线段树模板题 contest 线段树 T5


    Description

    给定一个长为n的序列,接下来m次操作,每次操作会对序列某段区间内所有数加上一个值,或是询问一段区间的和。


    Input

    第一行,n和m,代表序列长度为n,并有m个操作第二行有n个数字,表示序列中的每个元素接下来m行,每行形如Q a b 代表查询[a,b]的区间和,或C a b c 代表对[a,b]中的所有数都增加c


    Output

    每行输出对应每一个查询的结果


    Hint

    n,m <=10^5。


    Solution

    对于这道题我想说我查错十几分钟最后还是死在了long long格式化输入输出要用lld上面。。。(充分证明我有多么傻逼)


    呃感觉线段树就很像树状数组和静态RMQ结合起来了(???)然后其实感觉理解起来挺简单的就是建一颗树,二分地来存区间,然后访问的时候只需要去看区间的边界就可以了,因为他是二分的所以肯定是能找到要查询的区间的。然后单点修改也很简单就不说了区间修改的话其实就是用一个tag记录整个区间需要加的值,然后只需要依次传递,不需要每次区间修改都要把这个区间的结点的所有儿子都修改了,用tag标记然后等到要查询的时候再修改就可以了。


    注意事项:

    1.首先long long是必要的,然后long long要用lld啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊。。。。。
    2.然后就是如果是区间和的区间修改的话就要乘(r-l+1),X_Download的过程里面也需要乘(mid-l+1)和(r-mid)。
    3.我是傻逼,没了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #define maxn 200005
    #define mid ((l+r)>>1)
    #define int long long
    using namespace std;
    int leftt[maxn],rightt[maxn],TOL_seg[maxn],aa[maxn],lazytag[maxn];
    int root,newp,n,m,a,b,c;
    char s[maxn];
    void X_Upload(int now){
    	TOL_seg[now]=TOL_seg[leftt[now]]+TOL_seg[rightt[now]];
    }
    void X_Build(int &now,int l,int r){
    	now=++newp;
    	if(l==r){
    		TOL_seg[now]=aa[l];
    		return;
    	}
    	X_Build(leftt[now],l,mid);
    	X_Build(rightt[now],mid+1,r);
    	X_Upload(now);
    }
    void X_Download(int now,int l,int r){
    	if(lazytag[now]==0)return;
    	TOL_seg[leftt[now]]+=lazytag[now]*(mid-l+1);
    	TOL_seg[rightt[now]]+=lazytag[now]*(r-mid);
    	lazytag[leftt[now]]+=lazytag[now];
    	lazytag[rightt[now]]+=lazytag[now];
    	lazytag[now]=0;
    }
    void X_Update(int now,int l,int r,int x,int y,int dx){
    	if(x>r||y<l)return;
    	if(x<=l&&y>=r){
    		TOL_seg[now]+=dx*(r-l+1);
    		lazytag[now]+=dx;
    		return;
    	}
    	X_Download(now,l,r);
    	if(y<=mid){
    		X_Update(leftt[now],l,mid,x,y,dx);
    	}
    	else{
    		if(x>mid){
    		    X_Update(rightt[now],mid+1,r,x,y,dx);
    		}
    		else{
    			X_Update(leftt[now],l,mid,x,y,dx);
    			X_Update(rightt[now],mid+1,r,x,y,dx);
    		}
    	}
    	X_Upload(now);
    }
    int X_Search(int now,int l,int r,int x,int y){
    	if(x>r||y<l)return 0;
    	if(x<=l&&y>=r){
    		return TOL_seg[now];
    	}
    	X_Download(now,l,r);
    	return X_Search(leftt[now],l,mid,x,y)+X_Search(rightt[now],mid+1,r,x,y);
    }
    signed main(){
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&aa[i]);
    	}
    	X_Build(root,1,n);
    	for(int i=1;i<=m;i++){
    		scanf("%s",&s[i]);
    		if(s[i]=='Q'){
    			scanf("%lld%lld",&a,&b);
    			printf("%lld
    ",X_Search(root,1,n,a,b));
    		}
    		if(s[i]=='C'){
    			scanf("%lld%lld%lld",&a,&b,&c);
    			X_Update(root,1,n,a,b,c);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    ? 这是个很好的问题。Go 当前的 GC 显然做了一些额外的工作,但它也跟其他的工作并行执行,所以在具有备用 CPU 的系统上,Go 正在作出合理的选择。请看 https://golang.org/issue/17969 结束语(Closing notes) 通过研究 Go 垃圾收集器,我能够理解 Go GC 当前结构的背景以及它如何克服它的弱点。Go发展得非常快。如果你对 Go感兴趣,最好继
    Kombu is a messaging library for Python.
    pencil
    io loop select
    gevent 缺点
    pyopenssl
    秒杀系统“减库存”设计的核心逻辑
    Gokit微服务-服务链路追踪
    Go 代码审查建议
    Visual Studio Team Systems
  • 原文地址:https://www.cnblogs.com/virtual-north-Illya/p/10045175.html
Copyright © 2020-2023  润新知