NOIP2023 T2 三值逻辑 题解

题面

思路

乍一看好像很并查集,而且不太难,但是,

注意到:按顺序运行这 \(m\) 条语句

事情并没有那么简单。

比如说如下情况:

x1:=T
x2:=x1
x1:=F

这时,\(x_2\)就不能简单地指向\(x_1\),否则当\(x_1\)被修改时,\(x_2\)也会被修改。

那么如何解决这个问题呢?

其实有点可持久化的感觉。我们可以对于每次修改\(x_1\)时,为它新建一个版本。以后所有形如\(x_2:=x_1\)的赋值操作,\(x_2\)都指向最新的版本。可以以边的形式存储它们的对应关系,\(x_2:=x_1\)则由\(x_2\)向\(x_1\)指一条边权为0的边(下文称为正边),\(x_2:=-x_1\)则由\(x_2\)向\(x_1\)指一条边权为1的边(下文称为负边)(这些边权是干什么的?这是一会儿要用到的神奇妙妙工具)。最终的产物像若干个栈。每个位置都有一个栈,每个栈上都摞着若干个节点。

(图挂了)

像这样。有些东西没画,各位自行脑补。

可以观察到它是一个森林,森林中每棵树上的节点的值都相等。

题干中说,要让执行了所有语句后所有变量的最终值和初始值相等。那么我们可以从每个栈的栈底向栈顶指一条正边。于是我们得到了若干个环。最终的图也就是若干基环树,但是本文中的做法并没有用到什么基环树,笔者也不会基环树。

我们要找到只能初始化为\(U\)的位置,那么什么时候一个位置只能被初始化为\(U\)呢?

第一种情况,它在最后一次赋值(“栈顶”)中被直接或间接赋值为\(U\)。这是显然的。

第二种情况,它的“栈底”(或“栈顶”)处在一个环里,且这个环中有奇数条负边。这也是显然的。

显然我们要集中精力求第二种。

依次对每一个位置进行DFS,如果DFS到被明确地赋值了的节点(形如\(x_1:=T\)),那么回溯时返回这个值,赋给回到的节点。否则返回0(也可以是-1或任何你喜欢的数。如果你也设为0,那么记得将数组初始化为-1)。

如果DFS到了一个环,且当前经过的负边个数减去上一次到这个点时的负边个数是一个奇数,那么赋值为\(U\)。可以在DFS时以参数形式传递当前经过的负边个数,用数组存储上一次到某位置时的负边个数。这时我们的负边权值为1就派上了用场,路径的权值和即是负边个数。

于是此题得解。

注意,当出现自环时,不能简单粗暴地忽略或认为无解,这样会挂40分(别问我怎么知道的);而是把它也加进图里。因为它在栈中相当于上下两节点之间的连边,是可以存在的。此时注意赋值顺序,不要像笔者一样先把节点入栈再从该节点向栈顶连边。

实现

原谅我抽象的码风

#include <iostream>
#include <cstring>
#define N 300005
int to[N],top[N],wt[N];
bool vis[N];
int a[N];
int tlen[N];
int dfs(int x,int len)
{
if(a[x]>=0)
return a[x];
if(vis[x])
{
if((len-tlen[x])&1)
return a[x]=3;
return a[x]=0;
}
vis[x]=1;
tlen[x]=len;
if(!to[x])
return a[x]=0;
int tmp=dfs(to[x],len+wt[x]);
if(tmp==3||tmp==0)
a[x]=tmp;
else
{
if(wt[x])
a[x]=3-tmp;
else
a[x]=tmp;
}
vis[x]=0;
return a[x];
}
int main()
{
int c,t;
scanf("%d%d",&c,&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
memset(top,0,sizeof(top));
memset(to,0,sizeof(to));
memset(a,-1,sizeof(a));
memset(vis,0,sizeof(vis));
memset(tlen,0,sizeof(tlen));
int cnt=0;
for(int i=1;i<=n;i++)
top[i]=++cnt;
for(int i=1;i<=m;i++)
{
char opt;
std::cin>>opt;
if(opt=='+')
{
int u,v;
scanf("%d%d",&u,&v);
cnt++;
to[cnt]=top[v];
top[u]=cnt;
wt[cnt]=0;
}
if(opt=='-')
{
int u,v;
scanf("%d%d",&u,&v);
cnt++;
to[cnt]=top[v];
top[u]=cnt;
wt[cnt]=1;
}
if(opt=='T'||opt=='F'||opt=='U')
{
int v;
scanf("%d",&v);
top[v]=++cnt;
if(opt=='T')
a[cnt]=1;
else if(opt=='F')
a[cnt]=2;
else
a[cnt]=3;
}
}
for(int i=1;i<=n;i++)
if(top[i]!=i)
to[i]=top[i],wt[i]=0;
for(int i=1;i<=n;i++)
if(a[i]<0)
dfs(i,0);
int ans=0;
for(int i=1;i<=n;i++)
if(a[i]==3)
ans++;
printf("%d\n",ans);
}
}

\[\huge End
\]

P9869 [NOIP2023] 三值逻辑 题解的更多相关文章

  1. 你真的会玩SQL吗?让人晕头转向的三值逻辑

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  2. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  3. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  4. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  5. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  6. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  7. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  8. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  9. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  10. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. JDK 18 及以上使用标准输出流中文输出乱码问题

    著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 链接:https://stazxr.cn/2024/12/05/JDK-18-以上使用标准输出流中文输出乱码问题/ 来源:終わり ...

  2. WxPython跨平台开发框架之参数配置管理界面的设计和实现

    我曾经在2014年在随笔<Winform开发框架之参数配置管理功能实现-基于SettingsProvider.net的构建>介绍过基于.NET开发的参数配置管理界面,本篇随笔基于类似的效果 ...

  3. Python 2.7 十六进制字符数组 转 字符串 (字符是Unicode字符)

    有一串十六进制数据,是Uncode字符. import struct strhex='003100310031' buf = strhex.decode("hex") value= ...

  4. 中电金信智能视觉分析系统,以AI技术助力企业升级

    ​ 基于行业需求与业务痛点,中电金信推出了智能视觉分析系统.该系统是集视频接入.视频识别与分析.AI算法管理.异常报警等为一体,可提供视频安全监管标准的场景应用方案以及二次开发能力的通用智能视觉分析系 ...

  5. Qt编写地图综合应用51-离线瓦片地图下载

    一.前言 写这个离线地图下载器的初衷,就是为了方便自己的几个需要离线地图的程序,客户需求,既然地图程序已经可以支持离线地图,那如何获取到这些离线瓦片地图文件是个关键,而且这是这个功能的关键,拿到这些一 ...

  6. Linux 下挂载群晖 NAS 硬盘拓展空间(NFS)

    在群晖 NAS 上配置 开启 NFS 服务 打开群晖的 设置 - 文件服务 - NFS,把 NFS 服务勾选上,协议选最新即可. 配置文件夹的 NFS 权限 在 设置 - 共享文件夹 下,选择需要开启 ...

  7. [转]CMake:相关概念与使用入门

    CMake:相关概念与使用入门(一) CMake:搜索文件和指定头文件目录(三) CMake 子工程添加 根目录中他文件夹里的cpp文件 翻译 搜索 复制

  8. Type of the default value for 'data' prop must be a function的解决方法

    Type of the default value for 'data' prop must be a function的解决方法 问题现象 在写形如prop: {type: Array; defau ...

  9. IM消息ID技术专题(七):网易严选分布式ID的技术选型、优化、落地实践

    1.引言 在<IM消息ID技术专题>系列文章的前几篇中,我们已经深切体会到消息ID在分布式IM聊天系统中的重要性以及技术实现难度,各种消息ID生成算法及实现虽然各有优势,但受制于具体的应用 ...

  10. Kubernetes系列(四) - Pod和Pod调度

    目录 1. Pod的组成部分 2. Pod的优势 3. Pod的两种分类 3.1 普通的pod 3.2 静态pod(static pod) 4. 控制器controller的特点 4.1 Deploy ...