\(\\\)

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. Windows 10+Ubuntu 16.04在MBR分区上安装双系统之后没有Windows 10的启动菜单解决方法

    背景: 硬盘分区方式:MBR 硬盘容量256,Windows 100,Ubuntu 156,其中主分区安装的是Windows,Ubuntu安装在逻辑分区上,文件系统为Ext4,整个Ubuntu就挂载在 ...

  2. 苹果装WIN 7

    一.准备:1.8G或以上的正版U盘或者移动硬盘,提前备份U盘数据(2013款air要求安装64位系统,市面上比较多U盘不是正版盘,一般做不成功,要换盘) 2.64位纯净版Windows7 ISO的下载 ...

  3. 我的arcgis培训照片14

    来自:http://www.cioiot.com/successview-562-1.html

  4. 网页页面NULL值对浏览器兼容性的影响

    网页页面NULL值对浏览器兼容性的影响       近期做项目中一个页面中的input radio出现浏览器兼容性问题. 主要问题: 在谷歌浏览器,360急速模式和搜狗急速模式中给radio初始动态赋 ...

  5. [欧拉回路] poj 1300 Door Man

    题目链接: http://poj.org/problem?id=1300 Door Man Time Limit: 1000MS   Memory Limit: 10000K Total Submis ...

  6. Redis官网下载步骤(含windows版)

    ①.百度redis ,进入官网 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  7. 七夕节 看到很多停止更新的blog 莫名有点淡淡的忧桑

    又是一年七夕.又是一年单身.看到很多停止更新的blog, 仿佛看到了一茬一茬的程序猿 进入it 圈 又离开it圈,就有莫名的忧桑

  8. react 项目实战(九)登录与身份认证

    SPA的鉴权方式和传统的web应用不同:由于页面的渲染不再依赖服务端,与服务端的交互都通过接口来完成,而REASTful风格的接口提倡无状态(state less),通常不使用cookie和sessi ...

  9. 在不同的系统中的virtualbox中安装Ubuntu SDK

    对非常多的开发人员来说.你们可能使用的不是Ubuntu操作系统.在这样的情况下,开发人员须要在自己的操作系统中(OS X及Windows)安装virtualbox,并在VirtualBox中安装Ubu ...

  10. [办公应用]word 2007:全屏快捷键,让复制图片保持原样大小(office 全屏快捷键)

    最近同事咨询这两个问题: 1.word 2007内是否有全屏显示的快捷键,这样投影时,就可以快速切换到全屏. 2.从ppt或者excel复制一张较大的图片,word 2007 会默认让复制的图片缩小, ...