[ TJOI 2012 ] 防御
\(\\\)
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 ] 防御的更多相关文章
- 如何防御“神器”Mimikatz窃取系统密码?
Mimikatz是一款能够从Windows中获取内存,并且获取明文密码和NTLM哈希值的神器,本文将介绍如何防御这款软件获取密码. Mimikatz介绍 Mimikatz是一款能够从Windows认证 ...
- 2012杀毒软件排行榜TOP10强
2012杀毒软件排行榜TOP10强 1:avast!杀毒软件 来自捷克的avast!,已有数十年的历史,它在国外市场一直处于领先地位.avast!分为家庭版.专业版.家庭网络特别版.和服务 ...
- CSRF的攻击与防御(转)
add by zhj:CSRF之所有发生,是因为http请求中会自动带上cookies,我的解决办法是:前端不要将数据放在cookie中,而是放在其它本地存储 (HTML5中称之为Web Storag ...
- Windows Azure 安全最佳实践 - 第 1 部分:深度解析挑战防御对策
我每次与开发人员讨论将应用程序迁移到云时都围绕着两个主要问题. 1. 首先是业务.将应用程序迁移到云可以带来怎样的规模经济? 2. 其次是安全问题."云的安全性如何,尤其是Windows A ...
- spring mvc中实现csrf安全防御简记
1.csrf是什么 csrf全称是Cross-site request forgery,http://en.wikipedia.org/wiki/Csrf 危害:使受害用户在不经意间执行了不是用户意愿 ...
- XXE注入攻击与防御
在研究XXE注入攻击之前先了解一下什么是XXE 定义 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言.XML文档结构包括 ...
- Kerberos无约束委派的攻击和防御
0x00 前言简介 当Active Directory首次与Windows 2000 Server一起发布时,Microsoft就提供了一种简单的机制来支持用户通过Kerberos对Web服务器进行身 ...
- [转载] MySQL 注入攻击与防御
MySQL 注入攻击与防御 2017-04-21 16:19:3454921次阅读0 作者:rootclay 预估稿费:500RMB 投稿方式:发送邮件至linwei#360.cn,或登陆网页 ...
- 利用ModSecurity防御暴力破解
利用ModSecurity防御暴力破解 from:http://www.freebuf.com/articles/web/8749.html 2013-04-18 共553248人围观 ,发现 12 ...
随机推荐
- 【C++/数据结构】单链表的基本操作
#pragma once #ifndef _CLIST_H_ #define _CLIST_H_ #include <iostream> #include <assert.h> ...
- 混合式框架-AgileLite
Agile Lite是一个HTML5移动前端框架.支持jQuery和Zepto双引擎.而且提供与UI无关的独立框架,内置了Flat UI样式和Ratchet样式.同一时候也支持单页模式和多页模式开发. ...
- react-color 颜色选择器组件
demo链接:github demo 安装: npm install react-color --save 有一下几种类型组件 <AlphaPicker /> <BlockPicke ...
- Linux查看文件最后几行的命令
tail -n 20 filename说明:显示filename最后20行
- Html.RenderPartial使用三个参数
Html.RenderPartial("usercontrolurl", model, ViewDataDictionary) 当使用三个参数时可以这样使用: var data = ...
- Codeforces 690 C3. Brain Network (hard) LCA
C3. Brain Network (hard) Breaking news from zombie neurology! It turns out that – contrary to prev ...
- CentOS常用基础命令大全
这篇文章主要介绍了CentOS常用基础命令大全,学习centos的朋友需要掌握的知识,需要的朋友可以参考下 1.关机 (系统的关机.重启以及登出 ) 的命令shutdown -h now 关闭系统(1 ...
- D1 模拟赛
T1 note 数组开小 菜的真实 60分 题目大意: 一个字符串 分成若干段 使每段内都没有重复的字符 求最少的段数 思路: 可以贪心 #include<iostream> #inclu ...
- POJ 2728 Desert King (最优比例生成树)
POJ2728 无向图中对每条边i 有两个权值wi 和vi 求一个生成树使得 (w1+w2+...wn-1)/(v1+v2+...+vn-1)最小. 采用二分答案mid的思想. 将边的权值改为 wi- ...
- E20170602-ts
questionnaire n. 调查问卷; 调查表; アンケート不是英语 collection n. 征收; 收集,采集; 收藏品; 募捐; association n. 联想; 协会, ...