Description

到冬天了,这意味着下雪了!从农舍到牛棚的路上有N块地砖,方便起见编号为1…N,第i块地砖上积了fi英尺的雪
。在Farmer John的农舍的地窖中,总共有B双靴子,编号为1…B。其中某些比另一些结实,某些比另一些轻便。具
体地说,第i双靴子能够让FJ在至多si英尺深的积雪中行走,能够让FJ每步至多前进di。Farmer John从1号地砖出
发,他必须到达N号地砖才能叫醒奶牛们。1号地砖在农舍的屋檐下,N号地砖在牛棚的屋檐下,所以这两块地砖都
没有积雪。帮助Farmer John求出哪些靴子可以帮助他走完这段艰辛的路程。

Input

第一行包含两个空格分隔的整数N和B(1≤N,B≤10^5)。

第二行包含N个空格分隔的整数;第i个整数为fi,即i号地砖的积雪深度(0≤fi≤10^9)。输入保证f1=fN=0
下面B行,每行包含两个空格分隔的整数。第i+2行的第一个数为si,表示第i双靴子能够承受的最大积雪深度。
第i+2行的第二个数为di,表示第i双靴子的最大步长。输入保证0≤si≤10^9以及1≤di≤N-1

Output

输出包含N行

第i行包含一个整数:如果Farmer John能够穿着第i双靴子从1号地砖走到N号地砖,为1,否则为0

Sample Input

8 7
0 3 8 5 6 9 0 0
0 5
0 6
6 2
8 1
10 1
5 3
150 7

Sample Output

0
1
1
0
1
1
1
---------------------------------------------------------分割线-------------------------------------------------------------
题意:
给定一个长度为n的序列。有m次询问,每次询问给定两个数sidi一开始站在0这个位置,
每次你可以走不超过di的距离,但你到达的位置的数不能超过si,问能否走到n+1
 

这题的解法好像挺多,比如并查集?但是我还是用线段树了,因为讲师是这么讲的23333
思考对问题模型做一些转化,假如说有连续的长度为di的距离都大于si,那么显然你是无论如何都不能走过去
否则显然你是无论如何都能够走过去的
这样问题就变成了考虑一个长度为n的序列中,最长的连续的不能通行的长度是多少。
但是这个东西对于m次询问我们显然是不能暴力去搞的,这样肯定会T.
那么考虑一下我们是否可以把si的顺序调一下然后很方便的去搞。
因为我们很容易想到一个贪心就是如果我们将si按照从大到小排序时,我们每次只需要在原来的基础上删掉一些选择要走的砖即可
反之若是从小到大排,就是加上一些选择要走的砖
而如果我们再把砖的大小排一下序,那么在进行处理时我们插入砖的顺序就也是单调的了,这样遍历一遍复杂度O(n)
那么下面的问题就是处理插入或是删除以维护序列最长的不能通行的长度了
于是我们可以想到利用线段树维护这个信息,然后将si和序列从大到小或是从小到大排序,这样总复杂度是O((n+m)logn)
具体操作可以看看代码 

 #include<bits/stdc++.h>
#define ll long long
#define uint unsigned int
#define ull unsigned long long
using namespace std;
const int maxn = ;
struct enkidu {
int di, si, id;
}ask[maxn], a[maxn];
struct shiki {
int l, r, l_lin, r_lin;
int max_cnt;
}tree[maxn << ];
//l_lin表示这个区间从左边开始连续的不能走的长度
//r_lin表示这个区间从右边开始连续的不能走的长度
int n, m;
int ans[maxn]; inline int read() {
int x = , y = ;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') y = -;
ch = getchar();
}
while(isdigit(ch)) {
x = (x << ) + (x << ) + ch - '';
ch = getchar();
}
return x * y;
} inline bool cmp(enkidu a, enkidu b) {
return a.si < b.si;
} inline void maintain(int pos) {
int ls = pos << , rs = pos << | ;
if(tree[ls].r - tree[ls].l + == tree[ls].max_cnt)
tree[pos].l_lin = tree[ls].max_cnt + tree[rs].l_lin;
else tree[pos].l_lin = tree[ls].l_lin;
if(tree[rs].r - tree[rs].l + == tree[rs].max_cnt)
tree[pos].r_lin = tree[ls].r_lin + tree[rs].max_cnt;
else tree[pos].r_lin = tree[rs].r_lin;
tree[pos].max_cnt = max(tree[ls].max_cnt, tree[rs].max_cnt);
tree[pos].max_cnt = max(tree[pos].max_cnt, tree[ls].r_lin + tree[rs].l_lin);
} void build(int pos, int l, int r) {
tree[pos].l = l, tree[pos].r = r;
if(l == r) {
tree[pos].l_lin = tree[pos].r_lin = tree[pos].max_cnt = ;
return;
}
int mid = l + r >> ;
build(pos << , l, mid);
build(pos << | , mid + , r);
maintain-(pos);
} void update(int pos, int aim, int l, int r) {
if(l == r && l == aim) {
tree[pos].max_cnt = tree[pos].l_lin = tree[pos].r_lin = ;
return;
}
int mid = l + r >> ;
if(aim <= mid) update(pos << , aim, l, mid);
else update(pos << | , aim, mid + , r);
maintain(pos);
} int main() {
n = read(), m = read();
for(int i = ; i <= n; ++i) {
a[i].si = read();
a[i].id = i;
}
for(int i = ; i <= m; ++i) {
ask[i].si = read(), ask[i].di = read();
ask[i].id = i;
}
sort(ask + , ask + m + , cmp);
sort(a + , a + n + , cmp);
build(, , n);
int brick = ;//砖,表示第几块砖
for(int i = ; i <= m; ++i) {
while(brick < n && a[brick + ].si <= ask[i].si) {//如果可以走
brick++;
update(, a[brick].id, , n);
}
if(tree[].max_cnt < ask[i].di) ans[ask[i].id] = ;
}
for(int i = ; i <= m; ++i) printf("%d\n", ans[i]);
return ;
}

Bzoj[Usaco2018 Feb]5194 Snow Boots(线段树)的更多相关文章

  1. bzoj 1593: [Usaco2008 Feb]Hotel 旅馆【线段树】

    参考:https://blog.csdn.net/u010336344/article/details/53034372 神一样的线段树 线段树上维护:ll从左开始最长空段:rr从右开始最长空段:le ...

  2. [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】

    题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...

  3. [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】

    题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过  1018,即使它在 ProblemSet 的第一页 ...

  4. [BZOJ 3888] [Usaco2015 Jan] Stampede 【线段树】

    题目链接:BZOJ - 3888 题目分析 首先,计算出每个线段在 x 坐标 0 处出现的时间开始点和结束点,就转成了时间轴上的线段. 然后就是看每条线段是否被 y 比它小的线段完全覆盖了.注意求出的 ...

  5. [BZOJ 3747] [POI 2015] Kinoman【线段树】

    Problem Link : BZOJ 3747 题解:ZYF-ZYF 神犇的题解 解题的大致思路是,当区间的右端点向右移动一格时,只有两个区间的左端点对应的答案发生了变化. 从 f[i] + 1 到 ...

  6. BZOJ.4137.[FJOI2015]火星商店问题(线段树分治 可持久化Trie)

    BZOJ 洛谷 一直觉得自己非常zz呢.现在看来是真的=-= 注意题意描述有点问题,可以看BZOJ/洛谷讨论. 每个询问有两个限制区间,一是时间限制\([t-d+1,t]\),二是物品限制\([L,R ...

  7. BZOJ.1805.[IOI2007]sail船帆(贪心 线段树)

    BZOJ 洛谷 首先旗杆的顺序没有影响,答案之和在某一高度帆的总数有关.所以先把旗杆按高度排序. 设高度为\(i\)的帆有\(s_i\)个,那么答案是\(\sum\frac{s_i(s_i-1)}{2 ...

  8. BZOJ.4825.[AHOI/HNOI2017]单旋(线段树)

    BZOJ LOJ 洛谷 这题不难啊,我怎么就那么傻,拿随便一个节点去模拟.. 我们只需要能够维护,将最小值或最大值转到根.模拟一下发现,对于最小值,它的右子树深度不变(如果存在),其余节点深度全部\( ...

  9. BZOJ.3653.谈笑风生(长链剖分/线段树合并/树状数组)

    BZOJ 洛谷 \(Description\) 给定一棵树,每次询问给定\(p,k\),求满足\(p,a\)都是\(b\)的祖先,且\(p,a\)距离不超过\(k\)的三元组\(p,a,b\)个数. ...

随机推荐

  1. MakeDown的使用

    Makedown的使用 之前有用博客园来写博客,但是因为它的界面不好看,所以中途就放弃了.后来也使用过"有道云笔记",发现其写的笔记的界面很简洁工整.有道云笔记的书写原理和Make ...

  2. spring boot(二):注解大全

    spring boot注解 @Autowired 注解的意思就是,当Spring发现@Autowired注解时,将自动在代码上下文中找到和其匹配(默认是类型匹配)的Bean,并自动注入到相应的地方去. ...

  3. 【洛谷 P2120】 [ZJOI2007]仓库建设(斜率优化)

    题目链接 斜率优化+1,好吧不水分了. 玩具装箱那题以后再做,当作复习吧. \(f[i]=f[j]-(sum[i]-sum[j])*dis[i]+p[i]\) \(f[j]=-dis[i]*sum[j ...

  4. centos6.5 导入matplotlib报错 No module named '_tkinter

    1.解决方案 在centos系统下,导入matplotlib时,出现ImportError: No module named ‘_tkinter’的错误,首先 yum list installed | ...

  5. Vue SPA 首屏加载优化实践

    写在前面 本文记录笔者在Vue SPA项目首屏加载优化过程中遇到的一些坑及优化方案! 我们以 vue-cli 工具为例,使用 vue-router 搭建SPA应用,UI框架选用 element-ui ...

  6. Markdown tutorial [repost]

    1. italic We'll start by learning two basic elements in text formatting: italics and bold. In these ...

  7. CRF原理解读

    概率有向图又称为贝叶斯网络,概率无向图又称为马尔科夫网络.具体地,他们的核心差异表现在如何求  ,即怎么表示  这个的联合概率. 概率图模型的优点: 提供了一个简单的方式将概率模型的结构可视化. 通过 ...

  8. Hive ORC表的使用

    创建普通临时表: create table if not exists test_orc_tmp(   name string,   gender string,   cnt BIGINT )row ...

  9. Java从零到企业级电商项目实战

    欢迎关注我的微信公众号:"Java面试通关手册"(坚持原创,分享各种Java学习资源,面试题,优质文章,以及企业级Java实战项目回复关键字免费领取)回复关键字:"电商项 ...

  10. python基础===python自带idle的快捷键

    Ctrl + [ Ctrl + ]   缩进代码Alt+3 Alt+4 注释.取消注释代码行Alt+5 Alt+6 切换缩进方式 空格<=>TabAlt+/ 单词完成,只要文中出现过,就可 ...