Codeforces 605D - Board Game(树状数组套 set)
事实上是一道非常容易的题
很容易想到如果 \(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)的更多相关文章
- Codeforces 1139F Dish Shopping 树状数组套平衡树 || 平衡树
Dish Shopping 将每个物品拆成p 和 s 再加上人排序. 然后问题就变成了, 对于一个线段(L - R), 问有多少个(li, ri)满足 L >= li && R ...
- 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 ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
- 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings
谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- 【BZOJ-1452】Count 树状数组 套 树状数组
1452: [JSOI2009]Count Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1769 Solved: 1059[Submit][Stat ...
- 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...
- BZOJ1901 - Dynamic Rankings(树状数组套主席树)
题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t 要求你把第i个数修改为t 题解 动态的区间第k ...
- bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1384 Solved: 629[Submit][Stat ...
随机推荐
- GPIO位带操作点亮LED,且使用按键控制开关
1. 项目 类似与C51单片机的位操作使能引脚来点亮LED. 例如,sbit P0^0 = 0 LED1 = P0^0; 2. 代码 main.c #include "stm32f10x.h ...
- Vue3学习(八)之 Vue CLI多环境配置
一.前言 这里相对于之前就没那么麻烦了,通俗点说就是使用配置文件来管理多环境,实现环境的切换. 二.实现切换 1.增加开发和生产配置文件 在web的根目录下,创建开发环境切换配置文件.env.dev, ...
- Java:锁笔记
Java:锁笔记 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 1. Java 锁之公平锁和非公平锁 公平锁 是指多个线程按照申请锁的顺序来获取锁,类似于排队买 ...
- Scrum Meeting 0602
零.说明 日期:2021-6-2 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 困难 qsy PM&前端 完成后端管理 ...
- Beta阶段第一次会议
Beta阶段第一次例会 时间:2020.5.16 完成工作 姓名 完成任务 难度 完成度 lm 1.修订网页端信息编辑bug2.修订网页端登录bug(提前完成,相关issue已关闭) 中 100% x ...
- 2021.10.15考试总结[NOIP模拟77]
\(n=40\)考虑\(meet \;in \;the \;middle\) 某个元素有关的量只有一个时考虑转化为树上问题 对暴力有自信,相信数据有梯度 没了 UPD:写了个略说人话的. T1 最大或 ...
- 生产环境部署springcloud微服务启动慢的问题排查
今天带来一个真实案例,虽然不是什么故障,但是希望对大家有所帮助. 一.问题现象: 生产环境部署springcloud应用,服务部署之后,有时候需要10几分钟才能启动成功,在开发测试环境则没有这个问题. ...
- numpy读取本地数据和索引
1.numpy读取数据 np.loadtxt(fname,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False) 做一个 ...
- 计算机网络之传输层(传输层提供的服务及功能概述、端口、套接字--Socket、无连接UDP和面向连接TCP服务)
文章转自:https://blog.csdn.net/weixin_43914604/article/details/105451022 学习课程:<2019王道考研计算机网络> 学习目的 ...
- 如何系统学习C 语言(上)之 基础篇
大话C 语言(一) 初识C 语言 老实说,上大学之前我根本不知道什么是C 语言,所以当初学校开设这门课时,我是充满了好奇,所以当初我翻阅了大量的C 语言入门书籍,千篇一律,都是从一些概念.术语和理论讲 ...