Codeforces 题目传送门 & 洛谷题目传送门

事实上是一道非常容易的题

很容易想到如果 \(c_i\geq a_j\) 且 \(d_i\geq b_j\) 就连一条 \(i\to j\) 的边表示用完 \(i\) 之后可以用 \(j\)。然后跑 BFS。

直接跑复杂度是 \(n^2\),不过发现一个性质,那就是每个点最多被访问一次,故考虑用数据结构优化 BFS 的过程,具体来说,用树状数组套 set 维护所有 \((a_i,b_i)\) 的坐标,当访问到某个 \(j\) 时候就直接在树状数组套 set 上找出全部满足 \(a_i\leq c_j,b_i\leq d_j\) 的 \(i\) 并将其压入队列,并直接将这些点从 set 中删除。注意到每个点会恰好被删除一次,故总删除次数是线性的,再加上树状数组套 set 本身的 2log,复杂度 \(n\log^2n\)。

记得之前做过一道什么数据结构优化二分图染色的题来着的?这题思想似乎与那题差不多,都是利用每个点最多被访问一次这个性质,用数据结构优化暴力的过程(不过似乎这题比那题还容易一些)。

上帝不要惩罚我刷水题/kk

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=1e5;
int n,a[MAXN+5],b[MAXN+5],c[MAXN+5],d[MAXN+5];
int key[MAXN*2+5],cnt=0,uni[MAXN*2+5],num=0;
set<pii> st[MAXN*2+5];
void insert(int x,int y,int z){
for(int i=x;i<=num;i+=(i&(-i))) st[i].insert(mp(y,z));
}
void del(int x,int y,int z){
for(int i=x;i<=num;i+=(i&(-i))) st[i].erase(st[i].find(mp(y,z)));
}
vector<int> query(int x,int y){
vector<int> ret;
for(int i=x;i;i&=(i-1)){
set<pii>::iterator t=st[i].lower_bound(mp(y+1,0));
for(set<pii>::iterator it=st[i].begin();it!=t;++it){
ret.pb(it->se);
}
} return ret;
}
int dis[MAXN+5],from[MAXN+5];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
key[++cnt]=a[i];key[++cnt]=c[i];
} key[++cnt]=0;sort(key+1,key+cnt+1);key[0]=-1;
for(int i=1;i<=cnt;i++) if(key[i]!=key[i-1]) uni[++num]=key[i];
for(int i=1;i<=n;i++){
a[i]=lower_bound(uni+1,uni+num+1,a[i])-uni;
c[i]=lower_bound(uni+1,uni+num+1,c[i])-uni;
}
for(int i=1;i<=n;i++) insert(a[i],b[i],i);
memset(dis,-1,sizeof(dis));queue<int> q;
vector<int> v=query(1,0);
for(int i=0;i<v.size();i++) dis[v[i]]=1,q.push(v[i]),del(a[v[i]],b[v[i]],v[i]);
while(!q.empty()){
int x=q.front();q.pop();v=query(c[x],d[x]);
for(int i=0;i<v.size();i++){
int t=v[i];dis[t]=dis[x]+1;from[t]=x;q.push(t),del(a[t],b[t],t);
}
}
if(dis[n]==-1) printf("-1\n");
else{
printf("%d\n",dis[n]);vector<int> v;
for(int i=n;i;i=from[i]) v.pb(i);
reverse(v.begin(),v.end());
for(int i=0;i<v.size();i++) printf("%d ",v[i]);
}
return 0;
}

Codeforces 605D - Board Game(树状数组套 set)的更多相关文章

  1. Codeforces 1139F Dish Shopping 树状数组套平衡树 || 平衡树

    Dish Shopping 将每个物品拆成p 和 s 再加上人排序. 然后问题就变成了, 对于一个线段(L - R), 问有多少个(li, ri)满足  L >= li && R ...

  2. Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)

    E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...

  3. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

  4. 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings

    谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...

  5. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

  6. 【BZOJ-1452】Count 树状数组 套 树状数组

    1452: [JSOI2009]Count Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1769  Solved: 1059[Submit][Stat ...

  7. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

  8. BZOJ1901 - Dynamic Rankings(树状数组套主席树)

    题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t  要求你把第i个数修改为t 题解 动态的区间第k ...

  9. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

随机推荐

  1. tcl概述

    tcl,全名tool command language,是一种通用的工具语言. 1)每个命令之间,通过换行符或者分号隔开: 2)tcl的每个命令包含一个或者多个单词,默认第一个单词表示命令,第二个单词 ...

  2. cassandra表中主键的类型

    cassandra表中主键的类型及区分? 一.类型及区分 二.参考文章 一.类型及区分 Cassandra的4种Key Primary Key 主键 Composite Key,Compound Ke ...

  3. 吴恩达深度学习课后习题第5课第1周第3小节: Jazz Improvisation with LSTM

    目录 Improvise a Jazz Solo with an LSTM Network Packages 1 - Problem Statement 1.1 - Dataset What are ...

  4. LeetCode:并查集

    并查集 这部分主要是学习了 labuladong 公众号中对于并查集的讲解,文章链接如下: Union-Find 并查集算法详解 Union-Find 算法怎么应用? 概述 并查集用于解决图论中「动态 ...

  5. 普通用户在命令终端使用Python脚本连入校园网

    普通用户在命令终端使用Python脚本连入校园网 想要连入校园网的步骤: 浏览器输入对应的IP地址,输入账号密码连网: 下载对应软件,输入账号密码连网: 而面对没有界面的服务器,而你又没有root权限 ...

  6. 基于JWT的Token身份验证

    ​ 身份验证,是指通过一定的手段,完成对用户身份的确认.为了及时的识别发送请求的用户身份,我们调研了常见的几种认证方式,cookie.session和token. 1.Cookie ​ cookie是 ...

  7. Alpha阶段发布声明

    发布声明 Alpha 1.Alpha版本功能说明 功能列表和详情图 模块 功能 展示 首页 查看首页博文,搜索博文,可供未登录用户使用 动态 查看推荐动态给未登录用户使用,登录用户可以查看关注动态.我 ...

  8. 微信小程序实现tabs选项卡

    选项卡在我们的日常开发中,使用的还是蛮多的,但是微信小程序中却没有直接提供选项卡组件,不过我们可以变通通过 scroll-view 和 swiper 组件来实现一个选项卡的功能. 需求: 实现一个选项 ...

  9. centOs7.6安装 mysql-8.0.27

    1.下载mysql 2.连接服务器 3.通过 rpm -qa | grep mariadb 命令查看 mariadb 的安装包 4.通过 rpm -e mariadb-libs-5.5.68-1.el ...

  10. 第一篇:《Kubernetes 入门介绍》

    前言:本文是一篇 kubernetes(下文用 k8s 代替)的入门文章,将会涉及 k8s 的技术历史背景.架构.集群搭建.一个 Redis 的例子,以及如何使用 operator-sdk 开发 op ...