\(\\\)

Description


有 \(n\) 人,第 \(i\) 个人有一个护甲值 \(a_i\)。

有 \(m\) 次操作,分为以下两种:

  • \(A\ l\ r\ x\) 对编号在 \([l,r]\) 内的人造成 \(x\) 点伤害。
  • \(Q\ p\) 求第 \(p\) 个人当前受到的伤害值之和。

护甲值的作用是,如果当前总伤害未超过护甲值,只对这个人造成一倍伤害。

当总伤害第一次 \(\ge\) 护甲值时护甲破了,以后 的攻击都造成二倍伤害,破甲时的攻击 只造成一倍伤害

  • \(n,m\le 10^5,x\le 10^4,a_i\le 10^6\)

\(\\\)

Solution


我们记 \(val_i\) 表示第 \(i\) 个人被破甲时累积的伤害值是多少,答案就是第 \(i\) 个人受到的总伤害值 \(\times 2-val_i\) 。

然后考虑如何求 \(val_i\) 。线段树 \(DFS\) 。

线段树维护当前节点收到的伤害之和,以及当前区间最小 剩余 护甲值。

每次攻击打 \(lazy\ tag\) ,同时判断区间最小值是否 \(\le 0\) 。

如果出现最小值 \(\le 0\) 的情况,就从当前节点 开始向下 \(DFS\) , $pushdown $ 之后,分别判断左右子树,只要子树最小就继续 \(DFS\) 这个子树。到了叶节点就可以统计对应位置的 \(val\) 值了。

记得修改之后及时 \(pushup\) ,为了不影响后续的判断,我们把更新过的叶节点剩余护甲值设为 \(inf\)。

并不需要循环,因为每次攻击时左右子节点至多被 \(DFS\) 一次就可以处理掉所有不合法情况。

因为每个节点至多被\(DFS\) 进去一次,所以复杂度还是 \(n\ log\ n\) 的。

以及 \(DFS\) 之前要先判断最小值是否 \(\le 0\),否则可能会出现多次进叶节点的情况。

\(\\\)

Code


#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100010
#define gc getchar
#define Rg register
#define mid ((l+r)>>1)
#define inf 1000000000
#define mod 1000000009
using namespace std; inline int rd(){
int x=0; bool f=0; char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return f?-x:x;
} int n,m,lim[N],val[N]; struct segment{ int root,ptr; inline int newnode(){return ++ptr;} struct node{int ls,rs,mn,tag;}c[N<<1]; inline void pushup(int rt){
c[rt].mn=min(c[c[rt].ls].mn,c[c[rt].rs].mn);
} inline void pushdown(int rt){
if(c[rt].tag){
c[c[rt].ls].tag+=c[rt].tag;
c[c[rt].ls].mn-=c[rt].tag;
c[c[rt].rs].tag+=c[rt].tag;
c[c[rt].rs].mn-=c[rt].tag;
c[rt].tag=0;
}
} void build(int &rt,int l,int r){
rt=newnode();
if(l==r){
c[rt].mn=lim[l];
return;
}
build(c[rt].ls,l,mid);
build(c[rt].rs,mid+1,r);
pushup(rt);
} void check(int rt,int l,int r){
if(l==r){
val[l]=lim[l]-c[rt].mn;
c[rt].mn=inf;
return;
}
pushdown(rt);
if(c[c[rt].ls].mn<=0) check(c[rt].ls,l,mid);
if(c[c[rt].rs].mn<=0) check(c[rt].rs,mid+1,r);
pushup(rt);
} void updata(int rt,int l,int r,int L,int R,int w){
if(l>R||r<L) return;
if(l>=L&&r<=R){
c[rt].tag+=w;
c[rt].mn-=w;
if(c[rt].mn<=0) check(rt,l,r);
return;
}
pushdown(rt);
if(L<=mid) updata(c[rt].ls,l,mid,L,R,w);
if(R>mid) updata(c[rt].rs,mid+1,r,L,R,w);
pushup(rt);
} int query(int rt,int l,int r,int p){
if(p>r||p<l) return 0;
if(l==r) return c[rt].tag;
pushdown(rt);
if(p<=mid) return query(c[rt].ls,l,mid,p)+c[rt].tag;
else return query(c[rt].rs,mid+1,r,p)+c[rt].tag;
} }tree; int res; int main(){
n=rd(); m=rd();
for(Rg int i=1;i<=n;++i) lim[i]=rd();
tree.build(tree.root,1,n);
char c;
for(Rg int i=1,x,y,w;i<=m;++i){
c=gc(); while(!isalpha(c)) c=gc();
if(c=='Q'){
x=rd();
if(val[x]) (res+=(tree.query(tree.root,1,n,x)*2-val[x])%mod)%=mod;
else (res+=tree.query(tree.root,1,n,x)%mod)%=mod;
}
else{
x=rd(); y=rd(); w=rd();
tree.updata(tree.root,1,n,x,y,w);
}
}
printf("%d\n",res);
return 0;
}

[ TJOI 2012 ] 防御的更多相关文章

  1. 如何防御“神器”Mimikatz窃取系统密码?

    Mimikatz是一款能够从Windows中获取内存,并且获取明文密码和NTLM哈希值的神器,本文将介绍如何防御这款软件获取密码. Mimikatz介绍 Mimikatz是一款能够从Windows认证 ...

  2. 2012杀毒软件排行榜TOP10强

    2012杀毒软件排行榜TOP10强 1:avast!杀毒软件       来自捷克的avast!,已有数十年的历史,它在国外市场一直处于领先地位.avast!分为家庭版.专业版.家庭网络特别版.和服务 ...

  3. CSRF的攻击与防御(转)

    add by zhj:CSRF之所有发生,是因为http请求中会自动带上cookies,我的解决办法是:前端不要将数据放在cookie中,而是放在其它本地存储 (HTML5中称之为Web Storag ...

  4. Windows Azure 安全最佳实践 - 第 1 部分:深度解析挑战防御对策

    我每次与开发人员讨论将应用程序迁移到云时都围绕着两个主要问题. 1. 首先是业务.将应用程序迁移到云可以带来怎样的规模经济? 2. 其次是安全问题."云的安全性如何,尤其是Windows A ...

  5. spring mvc中实现csrf安全防御简记

    1.csrf是什么 csrf全称是Cross-site request forgery,http://en.wikipedia.org/wiki/Csrf 危害:使受害用户在不经意间执行了不是用户意愿 ...

  6. XXE注入攻击与防御

    在研究XXE注入攻击之前先了解一下什么是XXE 定义 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言.XML文档结构包括 ...

  7. Kerberos无约束委派的攻击和防御

    0x00 前言简介 当Active Directory首次与Windows 2000 Server一起发布时,Microsoft就提供了一种简单的机制来支持用户通过Kerberos对Web服务器进行身 ...

  8. [转载] MySQL 注入攻击与防御

    MySQL 注入攻击与防御 2017-04-21 16:19:3454921次阅读0     作者:rootclay 预估稿费:500RMB 投稿方式:发送邮件至linwei#360.cn,或登陆网页 ...

  9. 利用ModSecurity防御暴力破解

    利用ModSecurity防御暴力破解 from:http://www.freebuf.com/articles/web/8749.html 2013-04-18 共553248人围观 ,发现 12 ...

随机推荐

  1. 一步步搭建java信息管理系统00 - 前言

    开发前,先上效果图吧 信息管理系统,个人认为,以下几个因素是不可缺少的 多tab 因菜单比较多,右侧的树形一定要考虑,如果菜单还是多,那么顶部就要考虑起来了 以后想到什么,再添加吧. 看到easyui ...

  2. oracle索引简单使用

    --查询表索引 select * from user_ind_columns where table_name = upper('HY_PROJECT') and column_name = uppe ...

  3. PopupMenu的演示样例

    弹出菜单是停靠在一个View上的一个模式菜单. 假设View对象下方有空间,那么弹出菜单将显示在停靠对象的下方,否则会显示在上方. 这是很实用的: 源代码地址:http://download.csdn ...

  4. Dell PowerEdge RAID Controller (PERC) | Dell

      Dell PowerEdge RAID Controller (PERC)             The Dell™ PERC (PowerEdge™ RAID Controller) fami ...

  5. Ubuntu14.04 忘记rootpassword的解决方法

    对于windows操作系统,假设忘记管理员password,事实上还是蛮好解决的. 最简单的一种方式就是使用PE--电脑店,老毛桃等等,都能够非常完美的解决问题. 假设是Linux操作系统的话.事实上 ...

  6. 关于ping以及TTL的分析

    首先介绍一下ping这个工具 ping [目标] 的意思就是向目标发送几个数据包,之后假设目标接受到一个数据包.那么目标就会向发送ping的主机返回一个数据包 比方上图.我ping了百度的server ...

  7. VMWare中的Host-only、NAT、Bridge的比較

    VMWare有Host-only(主机模式).NAT(网络地址转换模式)和Bridged(桥接模式)三种工作模式. 1.bridged(桥接模式) 在这样的模式下.VMWare虚拟出来的操作系统就像是 ...

  8. TensorFlow的安装与CNN测试

    0.说明 在Google开源该框架之后便使用真实K40m卡测试,由于生产环境是CentOS6.6的操作系统,但是该框架需要在Python2.7环境下执行,CentOS6.6下折腾了一天没搞定,后来换成 ...

  9. 【Android基础】App签名与打包

    签名的意义 1. 为了保证程序开发人员的合法 2. 防止部分人通过使用同样的Package Name(包名)来混淆替换已安装的程序 3. 保证我们每次公布的版本号的一致性(保证签名一致才干升级) 签名 ...

  10. 定时删除clientmqueue

    * *  */1 * * cd /var/spool; cp -r clientmqueue /home/data/xl_project/var_spool_clientmqueue_$(date + ...