题意

题目链接

有\(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. js闭包之我见

    很久前的一个问题终于得以解决,内心是无比喜悦的,不多说,先上代码: function test(){ for(var i=0;i<5;i++){ window.onclick=function( ...

  2. 关于MySQL连接抛出Authentication Failed错误分析

    [问题描述] 在应用端,偶尔看到有如下报错: Authentication to host 'xxxx' for user 'yyyy' using method 'mysql_native_pass ...

  3. 【learning】vim爆改记 (如何让vim用起来像devc++)

    由于本蒟蒻NOIP人品大爆发,能去冬令营,故准备开始练习使用linux下的IDE:vim 在dalao DTZ的帮助下,我装好了vim,并做了最初的配置. 然而........好难用啊,怎么和devc ...

  4. linux 手动释放buff/cache

    为了解决buff/cache占用过多的问题执行以下命令即可 syncecho 1 > /proc/sys/vm/drop_cachesecho 2 > /proc/sys/vm/drop_ ...

  5. CharacterRangeTable

    转载:https://github.com/jacoco/jacoco/wiki/CharacterRangeTable This page discusses a not yet available ...

  6. go语言接受者的选取

    何时使用值类型 1.如果接受者是一个 map,func 或者 chan,使用值类型(因为它们本身就是引用类型).2.如果接受者是一个 slice,并且方法不执行 reslice 操作,也不重新分配内存 ...

  7. java.lang.ArithmeticException: Rounding necessary

    这个错误就是精度丢失问题 https://blog.csdn.net/qq496013218/article/details/70792655

  8. 移动设备的HTML页面中图片实现滚动加载

    如今移动互联网风靡全球,移动页面的元素也是丰富多彩,一个移动页面的图片超过10张已经是再正常不过的事情了.但是相对,很多移动用户还停留在2G,3G这样的网络中.那么这样带宽的用户,在浏览这样的页面时, ...

  9. 转载《浅析MVC框架中View层的优雅设计及实例》

    在基于B/S的应用程序开发中,从基本的技术分工上来说就是两大块,一是软件显示界面,另一个是程序逻辑.在N年前的脚本语言时代,无论是asp.php还是jsp,我们基本是都是把这两者柔和在一起的.尽管我们 ...

  10. 【LeetCode题解】141_环形链表

    目录 141_环形链表 描述 解法一:哈希表 思路 Java 实现 Python 实现 解法二:双指针(龟兔算法) 思路 Java 实现 Python 实现 141_环形链表 描述 给定一个链表,判断 ...