哭泣的阿木木

Time limit 1000 ms
Description
题目链接https://csustacm.fun/problem/1094
没啥用的背景故事:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1.将区间[L,R]绷带的价格增加k元
2.将区间[L,R]绷带的价格减少k元
3.将第i种绷带的价格变为 bb 元
4.每次询问请输出区间[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

请注意数据范围


一如既往,没什么卵用但篇幅很长的背景emmm。。。
这题无脑线段树裸题,不过就像他的提示一样,会爆int

#include<cstdio>
#include<cstring>
#define debug(n) printf("%d ",n)
#define minn(a,b) a<b?a:b
#define ll long long
#define mac 1000050
struct st
{
    ll l,r;
    ll w,f;
}tree[mac*4];
int l,r,k;
ll ans=0;
void build(int now,int l,int r);
void lazy(int now);
void change(int now,int id);
void change_pot(int now);
void ask(int now);
int main()
{
    int n,q;
    scanf ("%d%d",&n,&q);
    build(1,1,n);
    char s[5];
    for (int i=1; i<=q; i++){
        scanf ("%s",s);
        if (s[1]=='1') {
            scanf ("%d%d%d",&l,&r,&k);
            change(1,1);
        }
        else if(s[1]=='2'){
            scanf ("%d%d%d",&l,&r,&k);
            change(1,0);
        }
        else if(s[1]=='3'){
            scanf ("%d%d",&l,&k);
            change_pot(1);
        }
        else {
            scanf ("%d%d",&l,&r);
            ans=0;
            ask(1);
            printf ("%lld\n",ans);
        }
    }
    return 0;
}
void build(int now,int l,int r)
{
    tree[now].r=r,tree[now].l=l;
    if (l==r){
        scanf ("%lld",&tree[now].w);
        return;
    }
    int mid=(l+r)>>1;
    build (now*2,l,mid);
    build (now*2+1,mid+1,r);
    tree[now].w=tree[now*2].w+tree[now*2+1].w;
}
void lazy(int now)
{
    tree[now*2].f+=tree[now].f;
    tree[now*2+1].f+=tree[now].f;
    tree[now*2].w+=tree[now].f*(tree[now*2].r-tree[now*2].l+1);
    tree[now*2+1].w+=tree[now].f*(tree[now*2+1].r-tree[now*2+1].l+1);
    tree[now].f=0;
}
void change(int now,int id)
{
    if (tree[now].l>=l && tree[now].r<=r){
        if (!id){
            tree[now].w-=(ll)(tree[now].r-tree[now].l+1)*k;
            tree[now].f-=(ll)k;
        }
        else{
            tree[now].w+=((ll)tree[now].r-tree[now].l+1)*k;
            tree[now].f+=(ll)k;
        }
        return;
    }
    if (tree[now].f!=0)lazy(now);
    int mid=(tree[now].l+tree[now].r)>>1;
    if (l<=mid) change(now*2,id);
    if (r>mid) change(now*2+1,id);
    tree[now].w=tree[now*2].w+tree[now*2+1].w;
}
void change_pot(int now)
{
    if (tree[now].l==tree[now].r){
        tree[now].w=k;
        return;
    }
    if (tree[now].f!=0)lazy(now);
    int mid=(tree[now].l+tree[now].r)>>1;
    if (l<=mid) change_pot(now*2);
    else change_pot(now*2+1);
    tree[now].w=tree[now*2].w+tree[now*2+1].w;
}
void ask(int now){
    if (tree[now].l>=l && tree[now].r<=r){
        ans+=tree[now].w;
        return;
    }
    if(tree[now].f!=0) lazy(now);
    int mid=(tree[now].l+tree[now].r)>>1;
    if (l<=mid) ask(now*2);
    if (r>mid) ask(now*2+1);
}