哈理工OJ 2256 南西群岛海域·冲之岛近海(线段树区间更新+前缀和优化)
来源:互联网 发布:缸中之脑 知乎 编辑:程序博客网 时间:2024/04/29 13:57
题目链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2256
南西群岛海域·冲之岛近海
Time Limit: 3000 MS Memory Limit: 32768 K
Total Submit: 150(58 users) Total Accepted: 56(51 users) Rating: Special Judge: No
Description
报告称本海域有敌人反攻的前兆。编成以巡洋舰为中心的警戒部队,探明敌舰队动向。
假定当前敌舰采用了排成一行的阵型,m只敌舰分别在从1到m的位置上。(包括1和m。)在一场战斗的炮击阶段,每个舰娘都可以对一个范围内的所有敌舰造成一定的伤害。如果敌舰受到的伤害大于了自己的血量,就会被击沉。可是愚蠢、调皮又二次元的提督小林,他想知道任意一个区间有多少只敌舰被击沉了。你能帮助他么?
Input
输入由有多组数据组成,每组数据的第一行包括了三个整数m、n和q,分别表示敌舰的个数、舰娘的个数和小林的询问的个数。(1≤m,n≤10^5,q≤1000)
接下来的一行包括m个整数,表示每个敌舰的血量a。(1≤a≤10^9)
接下来的n行,每行包括了三个整数,L、R、x,表示对[L,R]范围内的所有敌舰造成x点伤害。(1≤L,R≤m, 1≤x≤100)
接下来的q行,每行包括了两个整数,L和R。你需要输出[L,R]范围内被击沉的敌舰的个数。
Output
对于每个查询输出包括一行,有一个整数,表示被击沉的敌舰的个数。
Sample Input
2 1 1
1 1
1 2 2
1 2
3 1 1
1 2 3
1 3 2
1 3
Sample Output
2
1
Source
“尚学堂杯”2015级程序设计竞赛(10月)正式赛
Author
TwIStOy
【思路分析】直接区间更新,然后前缀和搞一下就OK了,可能解题方法有点挫…。
【AC代码】
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;#define ll long longstruct node{ ll left,right,val,lazy,len;} c[100005];void build_tree(ll l,ll r,ll root){ c[root].left=l; c[root].right=r; c[root].lazy=0; c[root].len=(c[root].right-c[root].left+1); if(c[root].left==c[root].right) { scanf("%lld",&c[root].val); return ; } ll mid=(c[root].left+c[root].right)/2; build_tree(l,mid,root*2); build_tree(mid+1,r,root*2+1); c[root].val=c[root*2].val+c[root*2+1].val;}void pushdown(ll root){ if(c[root].lazy!=0) { c[root*2].lazy+=c[root].lazy; c[root*2+1].lazy+=c[root].lazy; c[root*2].val += c[root].lazy * (c[root*2].right - c[root*2].left + 1); c[root*2 + 1].val += c[root].lazy * (c[root*2 + 1].right - c[root*2 + 1].left + 1); c[root].lazy=0; }}ll search_tree(ll l,ll r,ll root){ if(c[root].left==l&&c[root].right==r) { return c[root].val; } if(c[root].lazy!=0) { pushdown(root); } ll sum; ll mid=(c[root].left+c[root].right)/2; if(mid<l) { sum=search_tree(l,r,root*2+1); } else if(r<=mid) { sum=search_tree(l,r,root*2); } else { sum=search_tree(l,mid,root*2)+search_tree(mid+1,r,root*2+1); } return sum;}void update_tree(ll l,ll r,ll root,ll x){ if(c[root].left==l&&c[root].right==r) { c[root].lazy+=x; c[root].val += x * (r - l + 1); return; } pushdown(root); ll mid=(c[root].left+c[root].right)/2; if(mid<l) { update_tree(l,r,root*2+1,x); } else if(mid>=r) { update_tree(l,r,root*2,x); } else { update_tree(l,mid,root*2,x); update_tree(mid+1,r,root*2+1,x); } c[root].val=c[root*2].val+c[root*2+1].val;}ll sum[100005];int main(){ ll n,m,q; while(~scanf("%lld%lld%lld",&m,&n,&q)) { memset(c,0,sizeof(c)); build_tree(1,m,1); ll a,b,x; for(int i=0; i<n; i++) { scanf("%lld%lld%lld",&a,&b,&x); update_tree(a,b,1,-x); } sum[0]=0; for(int i=1;i<=m;i++) { if(search_tree(i,i,1)<0) { //printf("%lld**\n",search_tree(i,i,1)); sum[i]=sum[i-1]+1; } else { sum[i]=sum[i-1]; } } sum[m+1]=sum[m]; ll l,r; for(int i=1;i<=q;i++) { scanf("%lld%lld",&l,&r); printf("%lld\n",(sum[r]-sum[l-1])); } } return 0;}
- 哈理工OJ 2256 南西群岛海域·冲之岛近海(线段树区间更新+前缀和优化)
- hrbust 2256 南西群岛海域·冲之岛近海(暴力)
- HLG 2256 南西群岛海域 -冲之岛近海(数组运用)(hash应用)
- 哈理工OJ 2255 镇守府海域·镇守府近海(模拟题目)
- 哈理工OJ 1566 Countless Candies【线段树】【区间更新、点查询】
- hrbust 1041 哈理工oj 1041 Chocolate Auction【线段树+区间更新】
- 哈理工OJ 1189 区间最大值 II(线段树【简单】)
- 哈理工OJ 1983 Math(前缀和)
- 【线段树】PKU2777 区间更新区间询问(位优化)
- POJ3468(线段树之区间更新)
- 哈理工OJ 1161 Leyni(线段树)
- 哈理工OJ 2043 长长长长龙(线段树)
- 线段树之区间更新
- 线段树、前缀数组:HDU1591-Color the ball(区间更新、简单题)
- 线段树-区间单个点更新-区间和-区间最大
- Light-oj 1080 - Binary Simulation(线段树区间更新)
- 线段树入门 区间更新 单点查询 南阳oj 123
- 线段树入门 单点更新区间查询 南阳oj 116
- Zookeeper入门
- 微信支付 支付授权目录 多域名处理 代理转发
- 数据结构家族谱问题(map)
- 设计模式之10 - 门面模式Facade
- type为text的input标签的相关事件对比
- 哈理工OJ 2256 南西群岛海域·冲之岛近海(线段树区间更新+前缀和优化)
- JVM源码—教你傻瓜式编译openjdk7
- spring切面:接口:前后置增强
- 模拟
- 设计模式之11 - 享元模式FlyWeight
- 简单讲解KMP单模式匹配与AC算法多模式匹配(KMP篇)
- spring切面:接口:环绕增强
- Java虚拟机学习(8):查看JVM参数及值的命令行工具
- C语言:求第N个斐波那契数