题意

题目链接

有\(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. PHP 5.6 如何使用 CURL 上传文件

    以前我们通过 PHP 的 cURL 上传文件是,是使用“@+文件全路径”的来实现的: curl_setopt(ch, CURLOPT_POSTFIELDS, array( 'file' => ' ...

  2. Python小白学习之路(六)—— 【元祖】【元祖相关功能】

    元祖 tu = (111,'alex',(11,['aa','xhg',(78,43)],'aaa'),789,) 通过这个例子,我们看到元祖的特征: 是通过括号()括起来的 一般写元祖的时候,推荐子 ...

  3. 社区发现的3个评估指标:标准化互信息NMI,ARI指标,以及模块度(modularity)

    转载请注明出处:http://www.cnblogs.com/bethansy/p/6890972.html 一.已知真实社区划分结果 1.NMI指数,互信息和标准化互信息 具体公式和matlab代码 ...

  4. Flume搭建及学习(基础篇)

    转载请注明原文出处:http://www.cnblogs.com/lighten/p/6830439.html 1.简介 该文主要是翻译官方的相关文档,源地址点击这里.介绍一下Flume的一些基本知识 ...

  5. iphoneX 适配

    1.iphoneX的尺寸  375*812   上边有44px的危险区,下边有34px的危险区,剩下的是安全区. 2.viewport设值cover <meta name="viewp ...

  6. javascript技巧总结

    1.删除前后空格 String.prototype.trim = function () { return this.replace(/(^[ | ])|([ | ]$)/g, "" ...

  7. Linux下MyCat和MyCat_web的安装和配置

    Linux下MyCat和MyCat_web的安装和配置 Mycat 是一个数据库分库分表中间件 Mycat web 可以对 Mycat进行监控,这里分享一下 Mycat web 的搭建过程 详细内容可 ...

  8. vs2015 活动解决方案或项目由选择的源代码管理插件以外的插件管理

    1.vs2015切换源代码管理插件,svn无法切换到git,点击是将关闭项目 解决方案: 找到项目中.sln 文件,使用编辑器打开,将Svn-Managed = true 设置为false

  9. sql中替换换行符和空格的示例

    select DiscussID,L.Name as LocationName , C.Name as ClientName, REPLACE(BrandName,' ','') BrandName ...

  10. activemq控制面板含义

    Name 消息队列的名称 Number Of Pending Messages 等待消费的消息数量,即未出队列的消息数量.可以理解为总接收数-总出队列数 (未持久化的话,重启acmq后会清零) Num ...