• 差分+树状数组 线段树【P2357】 守墓人


    题目描述-->p2357 守墓人

    敲了一遍线段树,水过.

    树状数组分析

    主要思路:

    差分

    简单介绍一下差分(详细概念太麻烦,看下面.

    给定一个数组
    7 8 6 5 1 8 18 20 35 //瞎敲的emmm
    7 1 -2 -1 3 10 2  15//对应得到差分数组.
    我们发现从[1,i]求和,得到的就是我们的原数组对应值.(这就是差分.
    

    为什么用差分+树状数组?

    对应差分,我们修改一个位置都会对应影响一段区间.

    差分的话,我们修改一个位置就达到了修改后面区间的效果.

    而我们修改一个区间,只需要对于左端点增加k,右端点+1位置减去k即可.

    对应差分操作,区间修改操作,我们可以推导出下面的式子.


    图片来源-->@胡小兔

    学习一下(简单了解)就可以了.

    所以我们就可以很简单码出来.

    码量小又简单,树状数组你值得拥有

    安利一篇很好的写树状数组的blog

    --------------------代码---------------------

    /*
    目前树状数组解法rank1(吸氧
    Timeuse:214ms
    Creator:顾z
    Date:2018.09.07
    */
    #include<bits/stdc++.h>
    #define int long long
    #define IL inline
    #define RI register int
    #define lowbit(x) x&-x 
    IL void in(int &x){
        int f=1;x=0;char s=getchar();
        while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
        while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
        x*=f;
    }
    int n,m,last,opt,x,y,z,mian;
    int sum1[500002],sum2[500002];
    IL void add(int pos,int x)
    {
    	for(RI i=pos;i<=n;i+=lowbit(i))
    		sum1[i]+=x,sum2[i]+=pos*x;
    }
    IL long long query(int pos)
    {
    	long long res=0;
    	for(RI i=pos;i;i-=lowbit(i))
    		res+=(pos+1)*sum1[i]-sum2[i];
    	return res;
    } 
    main(void)
    {
    	in(n),in(m);
    	for(RI i=1;i<=n;i++)in(x),add(i,x-last),last=x;
    	for(RI i=1,opt;i<=m;i++)
    	{
    		in(opt);
    		switch(opt)
    		{
    			case 1:in(x),in(y),in(z),add(x,z),add(y+1,-z);break;
    			case 2:in(z),mian+=z;break;
    			case 3:in(z),mian-=z;break;
    			case 4:in(x),in(y);printf("%lld
    ",query(y)-query(x-1)+(x==1)*mian);break;
    			case 5:printf("%lld
    ",query(1)+mian);
    		}
    	}
    }
    

    再粘一下线段树代码 emm↓

    
    /*
    线段树就跑的有些慢了 emmm(未吸氧
    zkw线段树应该会更快一些.
    Timeuse:594ms
    Creator:顾z
    Date:2018.09.03
    */
    #include<bits/stdc++.h>
    #define int long long
    #define IL inline
    #define RI register int
    #define ls o<<1
    #define rs o<<1|1
    #define N 1000008
    IL void read(int &x){
        int f=1;x=0;char s=getchar();
        while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
        while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
        x*=f;
    }
    int n,f,tr[N],tg[N],mian,c[N];
    IL void up(int o){tr[o]=tr[ls]+tr[rs];return;}
    IL void build(int o,int l,int r)
    {
    	if(l==r)
    	{
    		read(tr[o]);
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(ls,l,mid);
    	build(rs,mid+1,r);
    	up(o);
    	return;
    }
    IL void down(int o,int l,int r)
    {
    	if(tg[o])
    	{
    		int mid=(l+r)>>1;
    		tg[ls]+=tg[o];tg[rs]+=tg[o];
    		tr[ls]+=tg[o]*(mid-l+1);
    		tr[rs]+=tg[o]*(r-mid);
    		tg[o]=0;	
    	}
    }
    IL int query(int o,int l,int r,int x,int y)
    {
    	if(x<=l&&y>=r)return tr[o];
    	down(o,l,r);
    	int res=0;
    	int mid=(l+r)>>1;
    	if(x<=mid)res+=query(ls,l,mid,x,y);
    	if(y>mid)res+=query(rs,mid+1,r,x,y);
    	return res;
    }
    IL void change(int o,int l,int r,int x,int y,int del)
    {
    	if(x<=l&&y>=r)
    	{
    		tg[o]+=del;
    		tr[o]+=del*(r-l+1);
    		return;
    	}
    	down(o,l,r);
    	int mid=(l+r)>>1;
    	if(x<=mid)change(ls,l,mid,x,y,del);
    	if(y>mid)change(rs,mid+1,r,x,y,del);
    	up(o);
    	return;
    }
    signed main()
    {
    	read(n),read(f);
    	build(1,1,n);
    	for(RI i=1,opt,x,y,z;i<=f;i++)
    	{
    		read(opt);
    		switch(opt)
    		{
    			case 1:read(x),read(y),read(z),change(1,1,n,x,y,z);break;
    			case 2:read(z),mian+=z;break;
    			case 3:read(z),mian-=z;break;
    			case 4:read(x),read(y),printf("%lld
    ",query(1,1,n,x,y)+(x==1)*mian);break;
    			case 5:printf("%lld
    ",query(1,1,n,1,1)+mian);break;
    		}
    	}
    }
    

    目前**树状数组解法rank1 **

    除特殊声明外,本博客作品均由顾z创作。 未经博主允许,不得转载
  • 相关阅读:
    [官网]CREATE EXTENSION PostGreSQL 创建函数的方法
    Notepad++的一个用法 转换为unix 格式的文件
    LLVM的安装
    Linux 下面RPM 安装的SQLSERVER 修改字符集的方法
    Linux 下面 Sqlserver 2017 的简单安装
    Linux下面将windows写的脚本转换成 Linux 格式的文件
    PostgreSQL 安装了contrib 之后 登录失败的问题
    Linux 下面 PG 的 uuid-ossp 包安装办法
    Chrome 离线安装插件的办法
    [新三板摘牌]国资企业济南华光光电去年终止拟IPO今年摘牌新三板
  • 原文地址:https://www.cnblogs.com/-guz/p/9612815.html
Copyright © 2020-2023  润新知