洛谷 P5332 - [JSOI2019]精准预测(2-SAT+bitset+分块处理)
七月份(7.31)做的题了,题解到现在才补,不愧是 tzc
首先不难发现题目中涉及的变量都是布尔型变量,因此可以考虑 2-SAT,具体来说,我们将每个人在每个时刻的可能的状态表示出来。我们开两个二维变量 \(\text{Live}(i,t)\) 表示第 \(i\) 个人第 \(t\) 个时刻还活着,\(\text{Dead}(i,t)\) 则表示第 \(i\) 个人在第 \(t\) 个时刻已经死了,那么题目给出的条件即对应这些布尔变量的一些推导关系,具体来说:
- 由于一个人死了不能复活,所以必有 \(\text{Dead}(i,t)\to\text{Dead}(i,t+1)\),同样地有逆否命题 \(\text{Live}(i,t+1)\to\text{Live}(i,t)\)
- 对于条件 \(0\),显然可以连边 \(\text{Dead}(x,t)\to\text{Dead}(y,t+1)\),同理逆否命题 \(\text{Alive}(y,t+1)\to\text{Alive}(x,t)\)
- 对于条件 \(1\),显然可以连边 \(\text{Alive}(x,t)\to\text{Dead}(y,t)\),同理逆否命题 \(\text{Alive}(y,t)\to\text{Dead}(x,t)\)
那么我们只要对建出来的图跑一遍 Tarjan,那么对于一个 \(i\),可能与它活到 \(T+1\) 时刻的居民数就是 \(n-1\) 再减去满足 \(\text{Alive}(i,T+1)\) 可以推到 \(\text{Dead}(j,T+1)\) 的居民 \(j\) 的数量。注意,如果一个居民 \(j\) 满足 \(\text{Alive}(j,T+1)\) 可以推到 \(\text{Dead}(j,T+1)\),那么它无论如何在 \(T+1\) 时刻都是死亡状态,对于这样的居民我们特判一下即可,具体来说,我们对于每个 \(i\) 去掉 \(\text{Alive}(i,T+1)\) 可以推到 \(\text{Dead}(j,T+1)\) 的点 \(j\) 的数量后,还需去掉满足 \(\text{Alive}(i,T+1)\) 推不到 \(\text{Dead}(j,T+1)\),但 \(\text{Alive}(j,T+1)\) 可以推到 \(\text{Dead}(j,T+1)\) 的 \(j\) 的数量。
这样暴力做空间复杂度是平方的,时间复杂度是三方的,一脸过不去的样子,因此考虑优化,首先可以注意到一件事情就是我们其实并不需要缩点,因为在连出来的这张图中,只存在 \(\text{Alive}\to\text{Alive},\text{Dead}\to\text{Alive},\text{Dead}\to\text{Dead}\) 的边,并且 \(\text{Alive}\) 的边只会从时间后的连向时间前的,\(\text{Dead}\) 的边只会从时间前的连向时间后的,因此原图本身就是一个 DAG。其次,不难发现原图中很多点其实是没有用的,具体来说,我们只需要保留条件中的 \((x,t)\) 和 \((i,T+1)\),其他点都可以去掉,这样点数就降到了 \(\mathcal O(n+m)\),空间复杂度也就降了下来。
但是这样时间复杂度还是会爆炸,不过注意到此题我们只关心两个点之间的可达性,也就是一个取值只有 \(0/1\) 的布尔型变量,因此可以非常自然地想到 bitset
,具体来说我们以每个 \((i,T+1)\) 为起点进行一边 DFS 找出它能够到达哪些 \(\text{Dead}(i,T+1)\),用一个 bitset
维护,每次转移就遍历与当前点相邻的点然后令该点的答案或上与其相连的点的答案即可,由于加了记忆化搜索,因此我们每个点最多计算一次,复杂度就是 \(\mathcal O(\dfrac{(n+m)^2}{\omega})\),但这样空间复杂度又爆掉了。因此考虑一个据说非常 common 的套路:分块 DFS,具体来说我们每 \(B\) 个元素一块,然后我们每次处理每一块中的 \(\text{Dead}(i,T+1)\) 对所有点的贡献,这样我们 bitset 的大小只用开到 \(B\),时间复杂度 \(\mathcal O(\dfrac{n^2}{\omega}+\dfrac{n^2}{B})\),空间复杂度 \(\dfrac{nB}{\omega}\),取 \(B=10^4\) 时最优。
const int MAXN=5e4;
const int MAXM=1e5;
const int MAXV=3e5;
const int MAXE=1e6;
const int BLK=1e4;
int n,m,T,ncnt;set<int> nd[MAXN+5];
struct data{int opt,t,x,y;} a[MAXM+5];
map<int,int> id[2][MAXN+5];
int hd[MAXV+5],nxt[MAXE+5],to[MAXE+5],ec=0;
void adde(int u,int v){to[++ec]=v;nxt[ec]=hd[u];hd[u]=ec;}
int lv[MAXN+5],dd[MAXN+5],bel[MAXV+5],res[MAXN+5];
bitset<MAXN+5> must;
bitset<MAXV+5> vis;
bitset<BLK+5> st[MAXV+5];
void dfs(int x,int l,int r){
if(vis.test(x)) return;vis.set(x);st[x].reset();
if(l<=bel[x]&&bel[x]<=r) st[x].set(bel[x]-l+1);
for(int e=hd[x];e;e=nxt[e]){
int y=to[e];dfs(y,l,r);
st[x]|=st[y];
}
}
int main(){
scanf("%d%d%d",&T,&n,&m);
for(int i=1;i<=m;i++) scanf("%d%d%d%d",&a[i].opt,&a[i].t,&a[i].x,&a[i].y);
for(int i=1;i<=n;i++) nd[i].insert(T+1);
for(int i=1;i<=m;i++) nd[a[i].x].insert(a[i].t);
for(int i=1;i<=n;i++){
for(int x:nd[i]) id[0][i][x]=++ncnt,id[1][i][x]=++ncnt;
int pre0=0,pre1=0;
for(int x:nd[i]){
int cur0=id[0][i][x],cur1=id[1][i][x];
if(pre0) adde(pre0,cur0),adde(cur1,pre1);
pre0=cur0;pre1=cur1;
}
}
for(int i=1;i<=m;i++){
if(!a[i].opt){
int tt=*nd[a[i].y].upper_bound(a[i].t);
adde(id[0][a[i].x][a[i].t],id[0][a[i].y][tt]);
adde(id[1][a[i].y][tt],id[1][a[i].x][a[i].t]);
} else {
int tt=*nd[a[i].y].lower_bound(a[i].t);
adde(id[1][a[i].x][a[i].t],id[0][a[i].y][tt]);
adde(id[1][a[i].y][tt],id[0][a[i].x][a[i].t]);
}
}
for(int i=1;i<=n;i++){
lv[i]=id[1][i][T+1];
dd[i]=id[0][i][T+1];bel[dd[i]]=i;
}
for(int l=1,r=BLK;l<=n;l+=BLK,r+=BLK){
chkmin(r,n);vis.reset();bitset<BLK+5> cur;
for(int i=1;i<=n;i++) dfs(lv[i],l,r);
for(int i=l;i<=r;i++) if(st[lv[i]].test(i-l+1)) must.set(i),cur.set(i-l+1);
for(int i=1;i<=n;i++) res[i]+=r-l+1-(st[lv[i]]|cur).count();
}
for(int i=1;i<=n;i++) printf("%d%c",(must.test(i))?0:(res[i]-1)," \n"[i==n]);
return 0;
}
洛谷 P5332 - [JSOI2019]精准预测(2-SAT+bitset+分块处理)的更多相关文章
- [LOJ 3101] [Luogu 5332] [JSOI2019]精准预测(2-SAT+拓扑排序+bitset)
[LOJ 3101] [Luogu 5332] [JSOI2019]精准预测(2-SAT+拓扑排序+bitset) 题面 题面较长,略 分析 首先,发现火星人只有死和活两种状态,考虑2-SAT 建图 ...
- 【JSOI2019】精准预测(2-SAT & bitset)
Description 现有一台预测机,可以预测当前 \(n\) 个人在 \(T\) 个时刻内的生死关系.关系有两种: \(\texttt{0 t x y}\):如果 \(t\) 时刻 \(x\) 死 ...
- [JSOI2019]精准预测
题目 这么明显的限制条件显然是\(\text{2-sat}\) 考虑按照时间拆点,\((0/1,x,t)\)表示\(x\)个人在时间\(t\)是生/死 有一些显然的连边 \[(0,x,t+1)-> ...
- [JSOI2019]精准预测(2-SAT+拓扑排序+bitset)
设第i个人在t时刻生/死为(x,0/1,t),然后显然能够连上(x,0,t)->(x,0,t-1),(x,1,t)->(x,1,t+1),然后对于每个限制,用朴素的2-SAT连边即可. 但 ...
- [Bzoj5285][洛谷P4424][HNOI/AHOI2018]寻宝游戏(bitset)
P4424 [HNOI/AHOI2018]寻宝游戏 某大学每年都会有一次Mystery Hunt的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为新生 ...
- 洛谷 - P2257 - YY的GCD - 莫比乌斯反演 - 整除分块
https://www.luogu.org/problemnew/show/P2257 求 \(n,m\) 中 \(gcd(i,j)==p\) 的数对的个数 求 $\sum\limits_p \sum ...
- 洛谷 - UVA11424 - GCD - Extreme (I) - 莫比乌斯反演 - 整除分块
https://www.luogu.org/problemnew/show/UVA11424 原本以为是一道四倍经验题来的. 因为输入的n很多导致像之前那样 \(O(n)\) 计算变得非常荒谬. 那么 ...
- 洛谷P4135 作诗(不一样的分块)
题面 给定一个长度为 n n n 的整数序列 A A A ,序列中每个数在 [ 1 , c ] [1,c] [1,c] 范围内.有 m m m 次询问,每次询问查询一个区间 [ l , r ] [l, ...
- 【LOJ】#3101. 「JSOI2019」精准预测
LOJ#3101. 「JSOI2019」精准预测 设0是生,1是死,按2-sat连边那么第一种情况是\((t,x,1) \rightarrow (t + 1,y,1)\),\((t + 1,y, 0) ...
随机推荐
- django 1.11.16之环境搭建
django版本:django1.11.16 windows环境 python 3.6.3 !!!可先安装虚拟环境在进行环境搭建 1.安装django:pip install django= ...
- 二、Ansible基础之模块篇
目录 1. Ansible Ad-Hoc 命令 1.1 命令格式 1.2 模块类型 1.3 联机帮助 1.3.1 常用帮助参数 1.4 常用模块 1.4.1 command & shell 模 ...
- 什么是js事件,冒泡机制,事件捕获,默认行为
js事件: javascript使我们能够有能力创建动态页面,事件就是可以被js侦测到的行为,网页中每个元素都可以产生某些触发js函数的事件. 例如我们可以在用户点击某个按钮时产生一个click事件来 ...
- JAVA的array中indexOf
记得龙哥有个重构的文章里说直接判断啥的. 今天看JDK ArrayList,看到了他的 indexOf,他先判断,后进入循环,看似写了两遍for 循环,但是简单明了暴力.i like it . pub ...
- 【二食堂】Beta - 设计和计划
Beta设计和计划 需求再分析 根据助教.老师.用户以及各个团队PM的反馈意见,我们的项目目前有以下问题: 功能不完整 实用价值不高 两方面的缺陷,所以在Beta阶段,我们工作的中心还是完成项目规划中 ...
- Noip模拟66 2021.10.2
T1 接力比赛 思路就是直接做背包$dp$,然后看看容量相同的相加的最大值. 考虑如何在$dp$过程中进行优化 注意到转移方程的第二维枚举容量没有必要从容量总和开始枚举 那么我们便转移边统计前缀和,从 ...
- WPF PropertyChanged实现子属性通知
今天用WPF的View绑定了ViewModel的一个属性类,结果在属性类的子属性修改时,没有通知到UI. 如有要显示一个学生信息,采用WPF MVVM的模式,则前端代码 <StackPanel& ...
- IDEA插件开发,我是如何把公司的发布系统搬到IDEA里的
不得不说JetBrains公司直的非常的牛B,每一个程序员都能在JetBrains的官方网站找到一款属于自己的开发工具.这些开发工具在工作中给我们带来了巨大的便利.各种各样的基础插件,第三方插件,真是 ...
- Vulnstack内网靶场3
Vulnstack内网靶场3 (qiyuanxuetang.net) 环境配置 打开虚拟机镜像为挂起状态,第一时间进行快照,部分服务未做自启,重启后无法自动运行. 挂起状态,账号已默认登陆,cento ...
- Mac搭建以太坊私有链
记录过程与问题 一.安装 以go版本的ethereum进行安装 brew tap ethereum/ethereum brew install ethereum # 如果希望基于ethereum的de ...