ZOJ-3453---Doraemon's Sweet Bullet (线段树)
来源:互联网 发布:linux重命名命令 编辑:程序博客网 时间:2024/06/08 02:45
Doraemon likes to shoot his enemies with sweet bullets.
n "enemies" stand in a line, each with a life value li (the indexi increases from left to right side and starts from 1). Each time Doraemon shoots a sweet bullet from the right side. Theith bullet has a "critical range" ki. That is to say, it attacks the first enemy from right side whose life value is equal to or greater thanki.The life value of the attacked enemy will decrease to 1 immediately.
However, Doraemon finds a terrible fact that after an enemy is attacked, it will distribute the sweets to his friends and his friends' life value will increase by 1. For theith enemy, his friends are in a consecutive range from the aith enemy to thebith. Note that an enemy may be the friend of himself so that after being attacked his life value will be 2.
What's more, if a bullet can't find a target--there doesn't exist an enemy with life greater or equal thanki, all enemies' life will increase by 1.
Now Doraemon wants to know after m bullets were shot, what the maximum life value in all enemies is.
Input
The input contains multiple test cases.
Each test case begins with a line containing a single integer n (1 ≤ n ≤ 100000) indicating the number of enemies.
The following n lines describes enemies, one enemy each line. Each line contains three integers, the initial life valueli (1 ≤ li ≤ 10000) and his range of friendsai bi (1 ≤ ai ≤ bi≤ n) - that is, enemies with index fromai to bi (inclusive) are all his friends.
The following line contains an integer m (1 ≤ m ≤ 100000) indicating the number of bullets Doraemon has shot. The lastm lines follows, each with a single integer ki (1 ≤ ki ≤ 10000) describing the bullet's "critical range".
Different cases are separated by a blank line.
Process to the end of input.
Output
For each test case, output the maximum life value after shooting in a single line.
Sample Input
33 1 24 1 35 1 13421
Sample Output
6
Hint
Doraemon suggests that you should use scanf to read data.
题意:N个敌人排成一行,每个人都有一个生命值和朋友范围我方射出一颗值为K的子弹,这个子弹只能打中敌人生命值大于等于K的敌人。子弹从右往左,子弹只能打中一人,打中敌人以后,敌人的生命值降为1,他朋友范围内的人生命值加1;如果敌人范围内没有>=K的值,就是说子弹打不中敌人,那么所有人的生命值+1;
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,q;struct ee{ int val;int l;int r;int id;//id为编号}ren[100010];struct node{ int l,r; int val;//当前区间最大的血量 int lf,rf;//朋友区间 int id;//记录血量最大的人的编号 int tag;//增加的生命值}segtree[100010*4];void pushup(int root){ segtree[root].val=max(segtree[root<<1].val,segtree[root<<1|1].val); segtree[root].id=segtree[root<<1].val>segtree[root<<1|1].val?segtree[root<<1].id:segtree[root<<1|1].id;}void build(int root,int l,int r){ segtree[root].l=l; segtree[root].r=r; segtree[root].tag=0; if(l==r) { segtree[root].val=ren[l].val; segtree[root].lf=ren[l].l; segtree[root].rf=ren[l].r; segtree[root].id=ren[l].id; return ; } int mid=(l+r)>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r); pushup(root);}void pushdown(int root){ if(segtree[root].tag) { segtree[root<<1].val+=segtree[root].tag; segtree[root<<1|1].val+=segtree[root].tag; segtree[root<<1].tag+=segtree[root].tag; segtree[root<<1|1].tag+=segtree[root].tag; segtree[root].tag=0; }}void update(int root,int l,int r){ int ll=segtree[root].l; int rr=segtree[root].r; if(l<=ll&&rr<=r) { segtree[root].val++; segtree[root].tag++; return; } pushdown(root); int mid=(ll+rr)>>1; if(l<=mid)update(root<<1,l,r); if(r>mid) update(root<<1|1,l,r); pushup(root);}void _update(int root,int p){ int ll=segtree[root].l; int rr=segtree[root].r; if(ll==rr) { segtree[root].val=1; segtree[root].tag=0; return; } pushdown(root); int mid=(ll+rr)>>1; if(p<=mid) _update(root<<1,p); else _update(root<<1|1,p); pushup(root);}int _find(int root,int x){ if(segtree[root].l==segtree[root].r) return segtree[root].id; pushdown(root); if(segtree[root<<1|1].val>=x)//优先考虑右边 return _find(root<<1|1,x); else return _find(root<<1,x); pushup(root);}int main(){ while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) { scanf("%d%d%d",&ren[i].val,&ren[i].l,&ren[i].r); ren[i].id=i; } build(1,1,n); int x; scanf("%d",&q); while(q--) { scanf("%d",&x); if(x>segtree[1].val)//最大血量小于x,所有人血量加一 update(1,1,n); else { int id=_find(1,x);//找到第一个血量比x大的人的id _update(1,id);//将这个人血量置为1 update(1,ren[id].l,ren[id].r);//朋友学俩个都加1 } } printf("%d\n",segtree[1].val); } return 0;}
- ZOJ-3453---Doraemon's Sweet Bullet (线段树)
- ZOJ 3453 Doraemon's Sweet Bullet(线段树区间更新+单点更新+最值询问)
- ZOJ-3453:Doraemon's Sweet Bullet
- ZOJ3453 Doraemon's Sweet Bullet(线段树单点更新+区间更新+区间查询)
- zoj 3453 Cupid's Sweet Bullet
- zoj 3450Doraemon's Railgun
- ZOJ 3450 Doraemon's Railgun
- ZOJ 3452 Doraemon's Stone Game(高级博弈)
- ZOJ 3452 Doraemon's Stone Game(博弈)
- ZOJ-3447---Doraemon's Number Game (贪心+大数)
- zoj 3407 Doraemon's Cake Machine
- zoj 3407 Doraemon's Cake Machine
- ZOJ 3452 Doraemon's Stone Game
- ZOJ 3452 Doraemon's Stone Game
- ZOJ 3449:Doraemon's Number Game III
- ZOJ 3449 Doraemon's Number Game III
- ZOJ 3447 Doraemon's Number Game(优先队列+高精度运算)
- ZOJ 3446 Doraemon's Battle (三维dp+BFS)【打怪类模板】
- POJ3648 Wedding 【2-SAT】
- 第7章 IoC容器 III (Container) -- Spring4.3.8参考文档中文版
- 面试必备:LinkedList源码解析(JDK8)
- jsp跳出循环
- ProgressBar改变成我们想要的加载动画
- ZOJ-3453---Doraemon's Sweet Bullet (线段树)
- python入门(二十二):添加PATH路径
- Java运行时数据区域
- Linux下JDK1.8安装
- HDU 5881 Tea(规律)
- android中static的使用注意
- 去除list集合中重复项的几种方法
- 给定r,n求[1,r]内与n互素的个数有多少个?(容斥定理+位运算)
- pc连接rpliar,查看数据并编译rplidar_ros