题目描述-->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\n",query(y)-query(x-1)+(x==1)*mian);break;
case 5:printf("%lld\n",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\n",query(1,1,n,x,y)+(x==1)*mian);break;
case 5:printf("%lld\n",query(1,1,n,1,1)+mian);break;
}
}
}

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

差分+树状数组 线段树【P2357】 守墓人的更多相关文章

  1. 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树

    正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...

  2. 树状数组 && 线段树应用 -- 求逆序数

    参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...

  3. hdu1394(枚举/树状数组/线段树单点更新&区间求和)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...

  4. hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. hdu 5147 Sequence II【树状数组/线段树】

    Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...

  6. 「CodePlus 2017 11 月赛」Yazid 的新生舞会(树状数组/线段树)

    学习了新姿势..(一直看不懂大爷的代码卡了好久T T 首先数字范围那么小可以考虑枚举众数来计算答案,设当前枚举到$x$,$s_i$为前$i$个数中$x$的出现次数,则满足$2*s_r-r > 2 ...

  7. acwing 243. 一个简单的整数问题2 树状数组 线段树

    地址 https://www.acwing.com/problem/content/description/244/ 给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一: 1.“C l ...

  8. 区间操作---树状数组&&线段树

    涉及区间操作的一些套路必须要会呀 区间加减为了偷懒能不写线段树so我选择树状数组!! 但是区间乘除,最大值我想了想还是用线段树分块吧. 树状数组: 这里用网上的一张图: 这里灰色数组是原本的数组(a[ ...

  9. 数据结构--树状数组&&线段树--基本操作

    随笔目的:方便以后对树状数组(BIT)以及基本线段树的回顾 例题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 例题:hdu 1166 敌兵布阵 T ...

随机推荐

  1. 【题解】SDOI2018战略游戏

    被CNST的大小卡了好久.一定要开到18呀…… 首先,遇到这种带各种各样环的图先考虑是不是可以建立圆方树,在圆方树上求出答案.然后转化为圆方树之后,我们就将图转化到了树上.答案非常的明显:只要一个圆点 ...

  2. [bzoj3886] [USACO15JAN]电影移动Moovie Mooving

    题目链接 状压\(dp\). 注意到\(n\leq 20\)且每个只能用一次,所以很显然可以压缩每部电影看过没,记\(f[sta]\)为状态为\(sta\)时最多可以看多久. 转移时先枚举状态,然后枚 ...

  3. wmic的用法

    原始文章链接:http://blog.sina.com.cn/s/blog_5fb265c70100w4d0.html 一.wmic的基本命令格式简析 经常看网上的相关资料的话,读者可能会对wmic有 ...

  4. BZOJ1857 [Scoi2010]传送带 【三分法】

    题目链接 BZOJ1857 题解 画画图就发现实际上是在\(AB\)上和\(CD\)上分别选两个点\(E\),\(F\),使得\(t_{AE} + t_{EF} + t_{FD}\)最小 然后猜想到当 ...

  5. 【CF edu 30 A. Chores】

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  6. 这次OpenSSL HeartBleed漏洞是怎么一回事呢?

    “心脏出血”(Heartbleed)被称为互联网史上最严重的安全漏洞之一,波及了大量常用网站.服务,包括很多人每天都在用的 Gmail 等等,可能导致用户的密码.信用卡轻易泄露.但是我们可能对它还不是 ...

  7. JSOI2008 星球大战 [并查集]

    题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧 ...

  8. 牛客多校对抗第6场 A Singing Contest

    [20分]标题:A.Singing Contest | 时间限制:1秒 | 内存限制:256MJigglypuff is holding a singing contest. There are 2n ...

  9. java 多线程 原子性

    原子性 原子性:原子操作是不能被线程调度机制中断的操作,一旦操作开始,那么它就一定可以在可能发生的“上下文切换”之前(切换到其他线程执行)执行完毕. 依赖原子性是很棘手且很危险的,除非你是并发专家,否 ...

  10. koala 编译scss不支持中文解决方案

    方法一: 在scss文件第一行加上代码:@charset "utf-8"; 方法二: 进入到Koala 安装目录 C:\Koala\rubygems\gems\sass-3.4.9 ...