1 条题解
-
0
自动搬运
来自洛谷,原作者为

Minclxc
**搬运于
2025-08-24 21:40:13,当前版本为作者最后更新于2017-10-26 10:23:59,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
下面的题解管理员可以删了,改题了。
如果对于盾没爆前或者盾都是0的情况,一个线段树就可以了
现在问题是盾可以挡多少伤害(样例中2号1的盾可以挡2伤害)
这个可以直接在线段树上向下搜,因为每个叶子节点最多只会盾爆一次,所以效率是O(nlgn)的
具体操作是维护min,修改的时候区间减(需要lazy),每次找会爆盾的子树,爆盾的min改为maxint就好了
查询就是查路径上的伤害总和*2-盾挡的伤害或者伤害总和(盾没爆)
维护sum,不用下放(不用lazy),查询的时候统计即可
#include<cstdio> using namespace std; #define fo(a,b,c) for(int a=b;a<=c;a++) #define LL long long int read(){ int a=0,f=0;char c=getchar(); for(;c<'0'||c>'9';c=getchar())if(c=='-')f=1; for(;c>='0'&&c<='9';c=getchar())a=a*10+c-'0'; return f?-a:a; } int min(int a,int b){return a<b?a:b;} const int N=1e5+1,mo=1e9+9;//模数是1e9+9不是1e9+7 LL sum[N<<2],lazy[N<<2],boom[N],d[N],minx[N<<2]; void pushup(int rt){ minx[rt]=min(minx[rt<<1],minx[rt<<1^1]); } void pushdown(int rt){ if(minx[rt<<1]!=2e9)minx[rt<<1]-=lazy[rt]; if(minx[rt<<1^1]!=2e9)minx[rt<<1^1]-=lazy[rt]; lazy[rt<<1]+=lazy[rt],lazy[rt<<1^1]+=lazy[rt]; lazy[rt]=0; } void build(int l,int r,int rt){ if(l==r){ d[l]=read(); minx[rt]=d[l]?d[l]:2e9; return; } int m=l+r>>1; build(l,m,rt<<1); build(m+1,r,rt<<1^1); pushup(rt); } void change(int l,int r,int rt,int s){//除了这个函数都是线段树的函数,这个函数就是搜爆盾的函数 if(l==r){d[l]=d[l]-minx[rt]+s;minx[rt]=2e9;boom[l]=1;return;}//记录盾挡的伤害和爆炸标记 int m=l+r>>1; if(lazy[rt])pushdown(rt); if(s>=minx[rt<<1])change(l,m,rt<<1,s); if(s>=minx[rt<<1^1])change(m+1,r,rt<<1^1,s); pushup(rt); } void add(int l,int r,int rt,int L,int R,int c,LL s){ if(L<=l&&r<=R){ sum[rt]+=c; if(minx[rt]<=c)change(l,r,rt,c); if(minx[rt]!=2e9)minx[rt]-=c,lazy[rt]+=c; return; } s+=sum[rt]; if(lazy[rt])pushdown(rt); int m=l+r>>1; if(L<=m)add(l,m,rt<<1,L,R,c,s); if(m<R)add(m+1,r,rt<<1^1,L,R,c,s); pushup(rt); } int query(int l,int r,int rt,int p){ if(l==r)return sum[rt]%mo; int m=l+r>>1; if(p<=m)return(sum[rt]+query(l,m,rt<<1,p))%mo; else return(sum[rt]+query(m+1,r,rt<<1^1,p))%mo; } int main(){ int n=read(),q=read();LL ans=0; build(1,n,1); fo(i,1,q){ scanf("\n"); if(getchar()=='A'){ int L=read(),R=read(),c=read(); add(1,n,1,L,R,c,0); } else{ int x=read(); if(boom[x])ans=(ans+query(1,n,1,x)*2-d[x]+mo)%mo; else ans=(ans+query(1,n,1,x))%mo; } } printf("%lld",ans); return 0; }
- 1
信息
- ID
- 1701
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者