洛谷 P2357 守墓人

折月煮酒 提交于 2019-11-29 22:07:55

洛谷 P2357 守墓人

题目描述

在一个荒凉的墓地上

有一个令人尊敬的守墓人, 他看守的墓地从来

没有被盗过, 所以人们很放心的把自己的先人的墓

安顿在他那

守墓人能看好这片墓地是必然而不是偶然.....

因为....守墓人懂风水 0.0

他把墓地分为主要墓碑和次要墓碑, 主要墓碑

只能有 1 个, 守墓人把他记为 1 号, 而次要墓碑有

n-1 个,守墓人将之编号为 2,3...n,所以构成了一个有 n 个墓碑的墓地。

而每个墓碑有一个初始的风水值,这些风水值决定了墓地的风水的好坏,所以守墓人

需要经常来查询这些墓碑。

善于运用风水的守墓人,通过一次次逆天改命,使得自己拥有了无限寿命,没人知道

他活了多久。

这天,你幸运的拜访到了他,他要求你和他共同见证接下来几年他的战果,但不过他

每次统计风水值之和都需要你来帮他计算,算错了他会要你命 QAQ

风水也不是不可变,除非遭遇特殊情况,已知在接下来的 2147483647 年里,会有 n 次

灾难,守墓人会有几个操作:

1.将[l,r]这个区间所有的墓碑的风水值增加 k。

2.将主墓碑的风水值增加 k

3.将主墓碑的风水值减少 k

4.统计[l,r]这个区间所有的墓碑的风水值之和

5.求主墓碑的风水值

上面也说了,很多人会把先人的墓安居在这里,而且守墓人活了很多世纪→_→,墓碑

的数量会多的你不敢相信= =

守墓人和善的邀请你帮他完成这些操作,要不然哪天你的旅馆爆炸了,天上下刀子.....

为了活命,还是帮他吧

输入格式

第一行,两个正整数 n,f 表示共有 n 块墓碑,并且在接下来的

2147483647 年里,会有 f 次世界末日

第二行,n 个正整数,表示第 i 块墓碑的风水值

接下来 f 行,每行都会有一个针对世界末日的解决方案,如题所述,标记同题

输出格式

输出会有若干行,对 4 和 5 的提问做出回答

输入输出样例

输入 #1复制

输出 #1复制

说明/提示

20%的数据满足:1≤n≤100

50%的数据满足:1≤n≤6000

100%的数据满足:1≤n,f≤2*10^5

题解:

怎么说呢?这是我做过的唯一一道题目背景出的比我还%%#¥的人。

(真是一道好题)

线段树模板题。竟然是蓝?

我曾一度怀疑查1号节点的值该怎么搞。后来直接把x,y置成了1.

完美解决。

记得开Longlong

代码:

#include<cstdio> #define int long long #define lson pos<<1 #define rson pos<<1|1 using namespace std; const int maxn=2*1e5+1; int n,f; int a[maxn]; int tree[maxn<<2],lazy[maxn<<2]; void build(int pos,int l,int r) {     int mid=(l+r)>>1;     if(l==r)     {         tree[pos]=a[l];         return;     }     build(lson,l,mid);     build(rson,mid+1,r);     tree[pos]=tree[lson]+tree[rson]; } void mark(int pos,int l,int r,int k) {     tree[pos]+=(r-l+1)*k;     lazy[pos]+=k; } void pushdown(int pos,int l,int r) {     int mid=(l+r)>>1;     mark(lson,l,mid,lazy[pos]);     mark(rson,mid+1,r,lazy[pos]);     lazy[pos]=0; } void update(int pos,int l,int r,int x,int y,int k) {     int mid=(l+r)>>1;     if(x<=l && r<=y)     {         mark(pos,l,r,k);         return;     }     pushdown(pos,l,r);     if(x<=mid)         update(lson,l,mid,x,y,k);     if(y>mid)         update(rson,mid+1,r,x,y,k);     tree[pos]=tree[lson]+tree[rson]; } int query(int pos,int l,int r,int x,int y) {     int mid=(l+r)>>1;     int ret=0;     if(x<=l && r<=y)         return tree[pos];     pushdown(pos,l,r);     if(x<=mid)         ret+=query(lson,l,mid,x,y);     if(y>mid)         ret+=query(rson,mid+1,r,x,y);     return ret; } signed main() {     scanf("%lld%lld",&n,&f);     for(int i=1;i<=n;i++)         scanf("%lld",&a[i]);     build(1,1,n);     while(f--)     {         int k,x,y,z;         scanf("%lld",&k);         if(k==1)         {                scanf("%lld%lld%lld",&x,&y,&z);             update(1,1,n,x,y,z);         }         else if(k==2)         {             scanf("%lld",&z);             update(1,1,n,1,1,z);         }         else if(k==3)         {             scanf("%lld",&z);             update(1,1,n,1,1,-z);         }         else if(k==4)         {             scanf("%lld%lld",&x,&y);             printf("%lld\n",query(1,1,n,x,y));         }         else if(k==5)             printf("%lld\n",query(1,1,n,1,1));     }     return 0; }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!