题意

题目链接

有\(n\)张牌,每张牌有四个属性\((a, b, c, d)\),主人公有两个属性\((x, y)\)(初始时为(0, 0))

一张牌能够被使用当且仅当\(a < x, b < y\),使用后\(x\)会变为\(c\),\(y\)会变为\(d\)

问使用第\(n\)张牌的最小步数

Sol

直接从\((0, 0)\)开始大力BFS,那么第一次到达时就是最小的,同时记录一下前驱

现在的问题就是如何知道哪些点可以选,也就是找到所有\(a < x, b < y\)的点,可以直接树状数组+set维护

由于保证了每个元素只出现一次,因此总复杂度为\(O(nlog^2n)\)

#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define pb(x) push_back(x)
// #define int long long
#define LL long long
#define pt(x) printf("%d ", x);
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 2e5 + 10, INF = 1e9 + 10, mod = 1e9 + 7;
const double eps = 1e-9;
void chmax(int &a, int b) {a = (a > b ? a : b);}
void chmin(int &a, int b) {a = (a < b ? a : b);}
int sqr(int x) {return x * x;}
int add(int x, int y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
void add2(int &x, int y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
int mul(int x, int y) {return 1ll * x * y % mod;}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, a[MAXN], b[MAXN], c[MAXN], d[MAXN], vis[MAXN], dis[MAXN], pre[MAXN], da[MAXN], num;
#define lb(x) (x & (-x))
#define sit set<Pair>::iterator
set<Pair> T[MAXN];
void Add(int x, int v, int id) {
for(; x <= num; x += lb(x)) T[x].insert(MP(v, id));
}
vector<int> Query(int p) {
int x = a[p], y = b[p];
vector<int> res;
for(; x; x -= lb(x)) {
set<Pair> &now = T[x];
while(1) {
sit it = now.lower_bound(MP(y, 0));
if(it == now.end()) break;
res.pb(it -> se); now.erase(it);
}
}
return res;
} void Des() {
sort(da + 1, da + num + 1); num = unique(da + 1, da + num + 1) - da - 1;
for(int i = 1; i <= N; i++) {
a[i] = num - (lower_bound(da + 1, da + num + 1, a[i]) - da) + 1;
c[i] = num - (lower_bound(da + 1, da + num + 1, c[i]) - da) + 1;
if(i != N) Add(c[i], d[i], i);
}
}
void print(int t) {
printf("%d\n", dis[t]);
for(int u = t; ~u; u = pre[u]) printf("%d ", u);
}
void BFS() {
queue<int> q; q.push(N); pre[N] = -1; dis[N] = 1;
while(!q.empty()) {
int p = q.front(); q.pop();
if(a[p] == num && !b[p]) {print(p); return ;}
vector<int> nxt = Query(p);
for(int i = 0, t; i < nxt.size(); i++) {
if(vis[nxt[i]]) continue; vis[nxt[i]] = 1;
q.push(t = nxt[i]);
dis[t] = dis[p] + 1, pre[t] = p;
}
}
puts("-1");
}
signed main() {
N = read(); bool flag = 0;
for(int i = 1; i <= N; i++) {
a[i] = read(), b[i] = read(), c[i] = read(), d[i] = read();
da[++num] = a[i];
da[++num] = c[i];
flag |= (!a[i] && !b[i]);
}
if(!flag) return puts("-1");
Des();
BFS();
return 0;
}

cf605D. Board Game(BFS 树状数组 set)的更多相关文章

  1. Codeforces 605D - Board Game(树状数组套 set)

    Codeforces 题目传送门 & 洛谷题目传送门 事实上是一道非常容易的题 很容易想到如果 \(c_i\geq a_j\) 且 \(d_i\geq b_j\) 就连一条 \(i\to j\ ...

  2. bzoj1146整体二分+树链剖分+树状数组

    其实也没啥好说的 用树状数组可以O(logn)的查询 套一层整体二分就可以做到O(nlngn) 最后用树链剖分让序列上树 #include<cstdio> #include<cstr ...

  3. 【树状数组(二叉索引树)】轻院热身—candy、NYOJ-116士兵杀敌(二)

    [概念] 转载连接:树状数组 讲的挺好. 这两题非常的相似,查询区间的累加和.更新结点.Add(x,d) 与 Query(L,R) 的操作 [题目链接:candy] 唉,也是现在才发现这题用了这个知识 ...

  4. D 洛谷 P3602 Koishi Loves Segments [贪心 树状数组+堆]

    题目描述 Koishi喜欢线段. 她的条线段都能表示成数轴上的某个闭区间.Koishi喜欢在把所有线段都放在数轴上,然后数出某些点被多少线段覆盖了. Flandre看她和线段玩得很起开心,就抛给她一个 ...

  5. csu 1757(贪心或者树状数组)

    1757: 火车入站 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 209  Solved: 51[Submit][Status][Web Board] ...

  6. Codeforces Gym 100269F Flight Boarding Optimization 树状数组维护dp

    Flight Boarding Optimization 题目连接: http://codeforces.com/gym/100269/attachments Description Peter is ...

  7. gym 100589A queries on the Tree 树状数组 + 分块

    题目传送门 题目大意: 给定一颗根节点为1的树,有两种操作,第一种操作是将与根节点距离为L的节点权值全部加上val,第二个操作是查询以x为根节点的子树的权重. 思路: 思考后发现,以dfs序建立树状数 ...

  8. BZOJ 2434 阿狸的打字机(ac自动机+dfs序+树状数组)

    题意 给你一些串,还有一些询问 问你第x个串在第y个串中出现了多少次 思路 对这些串建ac自动机 根据fail树的性质:若x节点是trie中root到t任意一个节点的fail树的祖先,那么x一定是y的 ...

  9. BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2221  Solved: 1179[Submit][Sta ...

随机推荐

  1. 前端ajax传数据成功发送,但后端接收不到

    前几天遇到这样的问题,找了好久,是在ajax     contentType属性设置的问题. contentType默认是application/x-www-form-urlencoded    但是 ...

  2. javascript浅拷贝深拷贝理解记录

    javascript的深拷贝和浅拷贝问题几乎是面试必问的问题.好记性不如烂笔头,特此来记录一下自己对深拷贝浅拷贝的理解. 顾名思义,拷贝就是copy复制,在js中可以浅而理解为对一个对象或者数组的复制 ...

  3. Swinject 源码框架(二):循环依赖的解决

    可能存在循环依赖,比如 Parent 强制有 Child, Child 弱持有 Parent. 具体实现如下.Parent 初始化时,必须传入 Child,而 Child 初始化不必传入 Parent ...

  4. maven安装以及eclipse配置maven

    详细地址: http://jingyan.baidu.com/article/295430f136e8e00c7e0050b9.html 介绍安装maven,配置Maven环境变量,同时在Eclips ...

  5. 2019CVPR《Mask Scoring R-CNN》

    题目:<Mask Scoring R-CNN> CVPR 2019 Oral Paper(2017年783篇论文,获得口头报道的有215篇,oral paper很有含金量) 华中科技大学h ...

  6. Swift 使用 #warning

    swift 中没法使用#Warning来提示警告, 可以通过给TODO: FIXME:加上警告, 实现类似的效果. Build Phases ---> Run Script ---> ad ...

  7. js02--对象、函数、switch、for、异常、表单验证

    现在我们接着来继续学习有关js的一些基础. 1.undefined与null    undefined:当变量声明但尚未赋值时,它的类型就是undefined    null:表示一个不存在的对象,它 ...

  8. 简单shell expect程序

    1 expect程序 用的Ubuntu,本身没带expect,安装. sudo apt-get install expect (关于expect,参见http://www.tclchina.com/a ...

  9. Android 开发工具类 22_PullPersonService

    PULL 解析 XML import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; imp ...

  10. Python基础语法——(引号、字符串、长字符串、原始字符串、Unicode)

    一.单引号字符串和转义引号 当字符串中出现单引号'时,我们可以用双引号""将该字符串引起来:"Let's go!" 而当字符串中出现双引号时,我们可以用单引号' ...