J.哭泣的阿木木(线段树模板题)

哭泣的阿木木
Description

没啥用的背景故事:

在远古的恕瑞玛,有一个孤独而又忧郁的灵魂,阿木木。他在世间游荡,只为找到一个朋友。他遭受了一种远古的巫术诅咒,注定忍受永世的孤单,因为被他触碰就意味着死亡,被他爱怜就意味着蹂躏。所有自称见过阿木木的人都说他是一具活生生的死尸,身材矮小,通体捆绑着青灰色的绷带。世人围绕阿木木编造了许多神话故事、民间传说和史诗传奇,世代传颂了很长时间,以至于没人能分得清哪些是真相哪些是幻想。

恕瑞玛的匠人们对于一些特定的事物意见非常统一,比如,晨风永远向西吹、新月之夜吃太多是凶兆、最大的宝藏永远埋藏在最沉重的岩石下。然而,他们始终无法统一意见的,是关于阿木木的故事。

最常听说的故事里,阿木木是恕瑞玛开国皇室家族的成员,但这个家族染上了一种疾病,导致血肉以恐怖的速度腐烂凋零。作为家族中最年轻的孩子,阿木木被隔离在他自己的寝宫里,只有一个宫女隔着墙听他哭泣,于是他与这位宫女成为了朋友。她会为他讲述宫中的大事小情,还有自己祖母如何拥有神秘的力量,为这位孤独的皇子送去些许慰藉。

一天早晨,宫女带来了噩耗,阿木木的最后一位哥哥去世了,也就是说他已经成为恕瑞玛皇帝。宫女知道阿木木只能独自承担这一噩耗,悲伤涌上心头,她打开了寝宫的门锁,冲进去当面安慰他。阿木木忘情地抱住了她,但就在他们相互触碰到的同时,他惊讶地退了回去,他意识到,自己已经将家族的厄运降到了她身上。

宫女去世以后,她的祖母对这位年轻的皇帝施放了一道扭曲的枯萎诅咒。在她眼里,阿木木的行为等同于谋杀。后来她的诅咒灵验了,阿木木被永远困在了病痛折磨的那一瞬间,就像一只蚱蜢被裹在了蜂蜜琥珀中一般。

第二种最常听说的故事讲述的是另一位皇子,不过这是一位放纵于乖戾胡闹、残忍无情、杀人取乐的皇子,在这个故事中,阿木木在孩童时期就登基成为恕瑞玛帝国的皇帝,他坚信自己是太阳的宠儿,并要求所有臣民都将他奉为神明顶礼膜拜。

后来,阿木木决定寻找传说中的“昂戈之眼”,这是一件古老的圣物,被埋藏在一座镀金的墓穴之中,据说只要怀着一颗坚定无畏之心看它一眼,就能获得永生。阿木木开始了多年的寻宝之旅,他带着许多奴隶,扛着他穿过迷宫般的墓穴,舍命送死触发机关以便让皇帝畅通无阻。最终阿木木找到了那扇金色的巨石拱门,随后数十名石匠辛苦劳作,打开了封闭已久的石门。

年轻的皇帝冲了进去,怀着决心与“昂戈之眼”对视,这时他的奴隶们抓住了机会,封死了他身后的石门。有人说这位少年皇帝在黑暗中煎熬了数年,孤独感让他发疯,开始抓挠自己的皮肤,然后又不得不用绷带包扎。他的生命的确受到了“昂戈之眼”的赐福,在对自己过去罪孽的冥想和反省之中不老不死,但这种赐福也是一把双刃剑, 因为他同时也被诅咒永世孤独。 很久以后,经过连续的强烈地震,墓穴的地基被动摇破碎,这位皇帝终于逃了出来,对于自己与世隔绝的时间毫无概念,只想着要弥补自己曾经对生命造成的痛苦折磨。

还有一个关于阿木木的故事,说他是恕瑞玛第一任也是最后一任的约德尔统治者,他相信人性本善。为了用真凭实据反驳那些诋毁他的人,他发誓以乞丐的身份活下去,直到自己交到一位真正的朋友,以此说服帝国居民,他们约德尔人也会在恕瑞玛人需要帮助的时候在所不辞。

虽然有无数人在这位蓬头垢面的约德尔人身边经过,但却没有任何一个愿意停下来伸出援手。阿木木只能徒增悲伤,最后心碎地死去。但他的死还不是终结,因为有人发誓说看到这名约德尔人依然在沙漠中徘徊,永世搜寻着能让他重拾对人性的信心的那个人。

虽然这些故事各有千秋,但都有一些共同点。无论故事中的情形是怎样的,阿木木最后都以一种空虚落魄的状态死亡,随后经受永世的孤独和寂寞。他注定要永远寻找伙伴,但他的出现就意味着诅咒,他的触碰意味着死亡。在那些最漫长的冬夜,家家户户都必须将火烧到最旺,与此同时,殇之木乃伊的啜泣会在沙漠中时隐时现,绝望无助,讲述他永远都无法体会到友情的慰藉。

无论阿木木在寻找什么 –– 是赎罪、还是亲人、抑或只是单纯的善意之举 –– 有一件事是像晨风西吹一样确定的:他依然还在寻找。

阿木木.jpg

众所周知,阿木木是英雄联盟里面最好玩的英雄之一。

殇之木乃伊-阿木木是一位近战型英雄,拥有强大的技能属性、爆发能力强,拥有强力的群体控制技能。阿木木有着不错的护甲、血量成长和不错的DPS输出,拥有单体和群体两个控制技能,他将悲伤化为力量在战场上为队友保驾护航,发挥自身的优势辅助自己的队友gank并攻城略地,是一名优秀的tank英雄。

由于使用了过多的Q技能–绷带牵引,阿木木的绷带库存越来越少,有一天,阿木木去市场上采购绷带,市场上的绷带一共有n种,每一种绷带的价格为 a_ia
i
​ ,由于受到金融危机的影响,绷带的价格出现了一些波动,记性很差的阿木木将绷带价格的波动记录了下来,一共有Q次操作,有时阿木木会记录下新的价格波动,有时阿木木会计算一段区间[L,R]的绷带的价格之和,但是阿木木的计算器一不小心丢了,所以请聪明的你们回答阿木木每次询问的结果。

已知第i种价格波动有三种形式:

将区间[L,R]绷带的价格增加k元
将区间[L,R]绷带的价格减少k元
将第i种绷带的价格变为 bb 元
每次询问请输出区间[L,R] 内绷带的价格之和

Input

第一行输入N和Q(n∈[1,1000000],Q∈[1,1000000])代表N种绷带和Q次询问

接下来一行N个数ai,表示第i种绷带的价格,(ai∈[1,100000])

接下来Q次操作:

q1 L R k 表示将区间[L,R] 内的绷带价格增加k元 (k∈[1,10000],1<=L<R<=n)

q2 L R k 表示将区间[L,R]内的绷带价格减少k元 (k∈[1,10000],1<=L<R<=n)

q3 pos b表示将第pos种绷带的价格修改为b (pos∈[1,n],b∈[1,10000],1<=pos<=n)

q4 L R表示询问区间[L,R]内绷带的价格之和(1<=L<R<=n)

Output

输出每次询问的答案

(请注意过程中绷带的价格可能会变为负数)

Sample Input 1

9 9
10 8 5 7 5 2 6 1 10
q3 7 1
q1 4 7 5
q2 4 6 7
q4 1 5
q2 1 3 7
q2 3 6 2
q4 4 9
q1 4 9 9
q4 1 8
Sample Output 1

31
19
54
Hint

请注意数据范围

Source

2019年集训队选拔赛

思路:线段树模板题,没什么好解释的吧。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string>
#include<algorithm>
#include<set>
 
using namespace std;
 
#define ll long long 
struct node
{
	ll L;
	ll R;
	ll num;
	ll lazy;
	ll lenth;
}leaves[1000010*4];
 
void Push_Tree(ll k)
{
	if(leaves[k].lazy)
	{
		leaves[2*k].num = leaves[2*k].num + leaves[k].lazy*leaves[2*k].lenth;
		leaves[2*k+1].num = leaves[2*k+1].num + leaves[k].lazy*leaves[2*k+1].lenth;
		leaves[2*k].lazy += leaves[k].lazy;
		leaves[2*k+1].lazy += leaves[k].lazy;
		leaves[k].lazy = 0;
	}
}
 
void Build_Tree(ll l, ll r, ll k)
{
	leaves[k].L = l;
	leaves[k].R = r;
	leaves[k].lazy = 0;
	leaves[k].lenth = r - l + 1;
	if(l == r){
		scanf("%lld", &leaves[k].num);
		return;
	}
	ll mid = (l+r)/2;
	Build_Tree(l, mid, 2*k);
	Build_Tree(mid+1, r, 2*k+1);
	leaves[k].num = leaves[2*k].num+leaves[2*k+1].num;
}
 
void Update_Tree(ll l, ll r, ll add, ll k)
{
	if(leaves[k].L == l && leaves[k].R == r){
		leaves[k].num += leaves[k].lenth * add;
		leaves[k].lazy += add;
		return;
	}
	Push_Tree(k);
	ll mid = (leaves[k].L+leaves[k].R)/2;
	if(r <= mid) Update_Tree(l, r, add, 2*k);
	else if(l > mid)Update_Tree(l, r, add, 2*k+1);
	else{
		Update_Tree(l, mid, add, 2*k);
		Update_Tree(mid+1, r, add, 2*k+1);
	}
	leaves[k].num = leaves[2*k].num + leaves[2*k+1].num;
}
 
long long Search_Tree(ll l, ll r, ll k)
{
	if(leaves[k].L == l && leaves[k].R == r){
		return leaves[k].num;
	}
	Push_Tree(k);
	ll mid = (leaves[k].L+leaves[k].R)/2;
	if(r <= mid) return Search_Tree(l, r, 2*k);
	else if(l > mid) return Search_Tree(l, r, 2*k+1);
	else{
		return Search_Tree(l, mid, 2*k) + Search_Tree(mid+1, r, 2*k+1);
	}
}
 
int main()
{
	ll T, a, b, c, Q, s, n;
	while(~scanf("%lld%lld",&n,&Q))
	{
		Build_Tree(1,n,1);

		while(Q--)
		{
			char s[10];
			scanf("%s", s);
			if(s[1] == '1'){
				scanf("%lld%lld%lld", &a, &b, &c);
				Update_Tree(a,b,c,1);
			}
			else if(s[1] == '2')
			{
				scanf("%lld%lld%lld", &a, &b, &c);
				Update_Tree(a,b,-c,1);			
			}
			else if(s[1] == '3')
			{
				scanf("%lld%lld", &a, &b);
				ll kk = Search_Tree(a, a, 1);
				Update_Tree(a,a,b - kk,1);
			}
			else if(s[1] == '4')
			{
				scanf("%lld%lld", &a, &b);
				printf("%lld\n",Search_Tree(a,b,1));
			}
		}
	}
	return 0;
}

posted on 2019-03-27 22:18  tomjobs  阅读(109)  评论(0编辑  收藏  举报