[$>Codeforces \space 500 E. New Year Domino

题目大意 : 数轴上有序排列着 \(n\) 块多米诺骨牌, 第 \(i\) 块骨牌坐标为 \(p_i\) 长度为 \(l_i\)

如果推倒坐标为 \(p_i\) 的多米诺骨牌,那么区间 \([p_i, p_i + x_i]\) 中的多米诺骨牌都会被推倒,从而发生连锁反应.

现在有 \(q\) 组询问,每次询问之前可以让一些多米诺骨牌增加任意长度,代价是增加的长度之和。

询问的内容是每次推倒第 \(x\) 块骨牌,求要推倒第 \(y\) 块至少要花费的代价 (询问之间相互独立)

\(2 \leq n , q\leq 2 \times 10^5 \ 1 \leq p_i, l_i \leq 10^9\)

解题思路 :

观察发现,多米诺之间的连锁反应可以合并成一个块,每次从右到左每次新加骨牌的时候可以合并被它覆盖的块。

但是直接按照定义合并的话,只能保证一个块最左边的块可以推倒整个块,也就是说一个块的贡献只有在推倒整块最左边的骨牌时是合法的

仔细想了很久觉得并没有什么做法可以在线求出 \(x\) 对应的合法联通块,不妨大胆离线.

离线后按照询问的左端点排序,从右到左扫,边扫边用一个栈维护此时的联通块的状态和联通块之间的距离

对于每一个扫到的 \(i\),在其合并完之后处理 \(i\) 作为左端点的询问的答案

因为此时 \(i\) 左边的点还没有被加进联通块,所以从 \(i\) 开始推一定是合法的, 对于每一个左端点在 \(i\) 上的询问,算出两个联通块之间的距离就是答案

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
#define int ll
#define N (1000005)
int fa[N], l[N], r[N], st[N], sum[N], Ans[N], n, m, top;
struct Query{ int x, id; }; vector<Query> q[N];
inline int ask(int x){ return x == fa[x] ? x : fa[x] = ask(fa[x]); }
main(){
read(n);
for(int i = 1, x, y; i <= n; i++)
read(x), read(y), l[i] = x, r[i] = x + y;
for(int i = 1; i <= n; i++) fa[i] = i;
read(m);
for(int i = 1, L, R; i <= m; i++)
read(L), read(R), q[L].push_back((Query){R, i});
for(int i = n; i >= 1; i--){
int x = i;
while(top && l[st[top]] <= r[x]){
r[x] = Max(r[x], r[st[top]]);
fa[ask(st[top])] = x, top--;
}
if(top) sum[x] = sum[st[top]] + l[st[top]] - r[x];
st[++top] = x;
for(int j = 0; j < q[i].size(); j++){
int id = q[i][j].id, y = q[i][j].x;
Ans[id] = sum[ask(x)] - sum[ask(y)];
}
}
for(int i = 1; i <= m; i++) printf("%lld\n", Ans[i]);
return 0;
}

Codeforces 500 E. New Year Domino的更多相关文章

  1. CodeForces 500 A. New Year Transportation

    Description New Year is coming in Line World! In this world, there are n cells numbered by integers ...

  2. Codeforces 611C. New Year and Domino 动态规划

    C. New Year and Domino time limit per test 3 seconds memory limit per test 256 megabytes input stand ...

  3. 【codeforces 500E】New Year Domino

    [题目链接]:http://codeforces.com/problemset/problem/500/E [题意] 有n个多米诺骨牌; 你知道它们的长度; 然后问你,如果把第i骨牌往后推倒,然后要求 ...

  4. Codeforces 611C New Year and Domino DP+容斥

    "#"代表不能放骨牌的地方,"."是可以放 500*500的矩阵,q次询问 开两个dp数组,a,b,a统计横着放的方案数,b表示竖着放,然后询问时O(1)的,容 ...

  5. codeforces水题100道 第三题 Codeforces Beta Round #47 A. Domino piling (math)

    题目链接:http://www.codeforces.com/problemset/problem/50/A题意:一个NxM的举行中最多能放多少个1x2的矩形.C++代码: #include < ...

  6. CodeForces 611C New Year and Domino (动态规划,DP)

    题意:给定一个h*w的网格,里面只有.和#,.表示空的,#表示禁止的,然后有q个询问,询问中给你两个坐标,分别是左上和右下,求在这两者中间的有多少种(竖着和横着)两个相邻的点. 析:一看到这个题目,肯 ...

  7. Codeforces 611C New Year and Domino(二维前缀和)

    题目大概说给一个n*m个格子,格子'.'表示可以放东西,多次询问矩形区域(x1,y1)-(x2,y2)有几种放一张1*2的骨牌的方案数. 分别考虑横着竖着放,预处理出二维的前缀和,即sum[x][y] ...

  8. 洛谷 P5089: CodeForces #500 (Div. 1) B / 1012B : Chemical table

    题目传送门:洛谷P5089. 题意简述: 一张 \(n \times m\) 的表格,有一些格子有标记,另外一些格子没有标记. 如果 \((r_1,c_1),(r_1,c_2),(r_2,c_1)\) ...

  9. LibreOJ 题解汇总

    目录 #1. A + B Problem #2. Hello, World! #3. Copycat #4. Quine #7. Input Test #100. 矩阵乘法 #101. 最大流 #10 ...

随机推荐

  1. Bzoj1822 [JSOI2010]Frozen Nova 冷冻波

    Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1933  Solved: 608 Description WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖 ...

  2. bzoj 2200: [Usaco2011 Jan]道路和航线——拓扑+dijkstra

    Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...

  3. 透彻理解Spring事务设计思想之手写实现(山东数漫江湖)

    前言 事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败.事务具有4个特性:Atomicity(原子性),Consistency(一致性),Isolation(隔离性),D ...

  4. 关于$->aaa->bbb();的困惑

    第21行为什么可以调用test类的aa方法呢? 答:因为前一行(20)其已经被实例化了.所以现在的$this->obj其实可以相当于是一个对象. 20行和21行也可以写成如下 $xxoo = n ...

  5. 【Python学习笔记】Coursera课程《Using Databases with Python》 密歇根大学 Charles Severance——Week4 Many-to-Many Relationships in SQL课堂笔记

    Coursera课程<Using Databases with Python> 密歇根大学 Week4 Many-to-Many Relationships in SQL 15.8 Man ...

  6. devinet_ioctl

    Kernel: 4.12.6 deinet_ioctl:获取或者设置接口的地址,掩码,标记等信息: 注意,使用SIOCSIFFLAGS关闭设备,如果使用了别名,则删除对应ip,如果其为主ip,并且从i ...

  7. Linux 入门记录:十三、Linux 扩展权限

    一.默认权限 每一个终端都有一个 umask 属性,是用来确定新建文件或目录的默认权限的“掩码”(mask 有“掩码”的含义,至于 u,后面说). Linux 中一般有默认的权限掩码,使用命令 uma ...

  8. 【bzoj1798】【AHOI2009】维护序列

    练一下线段树模板,区间乘法. #include<bits/stdc++.h> #define lson (o<<1) #define rson (o<<1|1) ; ...

  9. java多线程以及Android多线程

    Java 多线程 线程和进程的区别 线程和进程的本质:由CPU进行调度的并发式执行任务,多个任务被快速轮换执行,使得宏观上具有多个线程或者进程同时执行的效果. 进程:在操作系统来说,一个运行的程序或者 ...

  10. Android IPC

    1. 什么是Android IPC IPC:inter-process Commnication跨进程的通信,多进程之间的通信,不同的操作系统有不同的通信方式,Android继承自Linux,但其IP ...