HDU4107 Gangster 线段树 段更新
来源:互联网 发布:java进程间同步 编辑:程序博客网 时间:2024/05/17 21:57
转载注明出处 http://blog.csdn.net/moedane
传送门 http://acm.hdu.edu.cn/showproblem.php?pid=4107
题意
代表有n个数(区间为[1,n]),m种操作。每个操作是给区间[l,r]加上一个数c,如果这个区间里面某个数大于等于给出的界限P,则加上2*c。输出全部操作结束之后最终的数列。
思路
线段树断更新。要记录的信息有区间最大值Max、区间最小值Min、区间累加的值addv。
要判断是否大于等于界限,则只要判断Min是否大于等于P、或者Max是否小于P。
if(Min >= P) add(2*c);
if(Max < p) add(c);
其他情况只需要往下再跑一层,直到达到上面的条件则可以做出相应操作。
这道题有点恶心的地方就是时间卡得紧,我把大部分预算换成位运算加上用输入挂才能950+ms勉强过。
代码
#include <iostream>#include <cstring>#include <cstdio>#include <string>#include <algorithm>#include <cmath>#include <ctime>#include <vector>#include <queue>#include <stack>#include <fstream>#include <map>#include <set>#define bug puts("here");using namespace std;typedef long long ll;const int maxn = 2 * 101000;const ll mod = 1e9+7;const int inf = 0x3f3f3f3f;const double PI = atan(1.0) * 4.0;const double eps = 1e-8;int n,m,P;struct Node{ int o,l,r; int Max,Min; int addv; int lenth() {return r - l + 1;} int mid() {return l + (r-l) / 2;} bool in(int L,int R) {return L <= l && R >= r;}};struct T{ Node t[maxn * 4]; void build(int o,int l,int r) { t[o].l = l; t[o].r = r; t[o].o = o; t[o].addv = t[o].Min = t[o].Max = 0; if(l == r) return; build(o<<1, l , t[o].mid()); build(o<<1|1, t[o].mid() + 1 , r); } void pushdown(int o) { if(t[o].addv && t[o].lenth() > 1) { t[o<<1].addv += t[o].addv; t[o<<1|1].addv += t[o].addv; t[o<<1|1].Min += t[o].addv; t[o<<1].Min += t[o].addv; t[o<<1|1].Max += t[o].addv; t[o<<1].Max += t[o].addv; t[o].addv = 0; } } void add(int o,int l,int r,int v) { if(t[o].in(l,r)){ if(t[o].Max < P){ t[o].addv += v; t[o].Max += v; t[o].Min += v; return; } if(t[o].Min >= P) { t[o].addv += v << 1; t[o].Max += v << 1; t[o].Min += v << 1; return; } } pushdown(o); if(l <= t[o].mid()) add(o<<1, l, r, v); if(r > t[o].mid()) add(o<<1|1, l , r, v); t[o].Min = min(t[o<<1].Min , t[o<<1|1].Min); t[o].Max = max(t[o<<1].Max , t[o<<1|1].Max); return; } int query(int o,int x) { if(t[o].lenth() == 1 && t[o].l == x){ return t[o].addv; } pushdown(o); if(x <= t[o].mid()) query(o<<1, x); else query(o<<1|1, x); }}tree;inline void scan(int &n){char cc;for (; cc = getchar(), cc<'0' || cc>'9';);n = cc - '0';for (; cc = getchar(), cc >= '0'&&cc <= '9';)n = n * 10 + cc - '0';}int main(){ while(~scanf("%d%d%d",&n,&m,&P)) { tree.build(1,1,n); for(int i=0;i<m;i++) { int l,r,c; scan(l); scan(r); scan(c); tree.add(1,l,r,c); } for(int i=1;i<n;i++){ printf("%d ",tree.query(1,i)); } printf("%d\n",tree.query(1,n)); }}
0 0
- HDU4107 Gangster 线段树 段更新
- 【线段树】 hdu4107 Gangster
- hdu4107 Gangster (线段树,段更新完后求数组内的值)
- HDOJ 4107 Gangster 线段树 成段更新变化
- hdu 4107 Gangster 线段树 成段更新
- 线段树-hdu-Gangster
- hdu 4107 Gangster 线段树
- hdu4107 线段树水题
- 线段树 成段更新
- 线段树 成段更新
- 线段树 成段更新
- [线段树 段更新] HDU
- HDU 4107 Gangster (线段树)
- HDU 4107 Gangster Segment Tree线段树
- hdu 4107 Gangster(线段树)
- HDOJ 题目4107 Gangster(线段树)
- 线段树 点更新和段更新
- 线段树 成段更新 hdu1698
- spring技术内幕12-HibernateTemplate对Hibernate的封装
- 心情生活。life
- [玩转SQL]:05 多表查询
- 3-4. 成绩转换(15)
- hibernate学习之SessionFactory的那些事
- HDU4107 Gangster 线段树 段更新
- Java如何实现文件打包下载功能
- 用AutoCompleteTextView实现历史记录提示
- C++ 时间相关问题
- 软件项目管理实践之日计划
- centos中安装g++
- em 弹性布局总结
- python for循环迭代序列
- hive 建表(Location, serde)