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. qnap nas 下的 nasconfig_fs.img.tgz 及相关的一点记录

    QNAP NAS 已安装EntWare(先前的Optware已废弃,不适用),可以使用 opkg 命令安装软件包(如想利用arp命令查看局域网的IP地址及对应物理网卡地址,可使用opkg instal ...

  2. MATLAB R2024a免费+破解版本(含密钥)

    强大功能 在使用2024a之前,我一直在使用2018b,最近数学建模+学年论文的摧残,让我看到了matlab新增的强大功能: Deep Learning Toolbox:新增支持 Transforme ...

  3. Less使用备忘录

    定义 Less (Leaner Style Sheets 的缩写) 是一门向后兼容的 CSS 扩展语言,动态样式语言. 使用方式 直接引入less.js文件 好处:能获取客户端的数据,从而进行进一步的 ...

  4. 前端每日一知之你需要知道的JSON.stringify

    脑图在线链接 本文内容依据[web开发]公众号精彩文章总结而来

  5. RepoDB:一个介于Dapper、EFCore之间.Net的ORM库

    推荐一个介轻量ORM和全功能ORM的开源项目. 01 项目简介 RepoDB 提供了基本操作所需的方法,同时也提供了一些高级功能,如第二层缓存.跟踪.仓储.属性处理器和批量/大量操作.支持的数据库,包 ...

  6. openEuler欧拉安装Gitlab

    1. 安装GitLab wget https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh sud ...

  7. Flutter枚举

    Flutter枚举 Enum Extension 在Dart2.7版本,Dart新增了扩展函数,使枚举相关的代码定义.调用更加简洁 通过扩展枚举定义方法 定义一个元素枚举 enum Element { ...

  8. 中电金信:GienTech动态|丰收之秋,公司多项目获得荣誉

    ​ 中电金信微电影<妙"笔"生花>获国资委表彰 ​ 近日,国务院国资委在京举行中央企业社会主义核心价值观主题微电影(微视频)展映发布活动.中电金信作品<妙&quo ...

  9. 中电资讯-乘风破浪数字经济,银行如何Hold数据?

    近期各类规划密集发布人行金融科技发展规划发布 金融标准化"十四五"规划发布 "十四五"信息化规划发布 -- 和数据应用有关的各项政策密集出炉 数字经济发展中如何 ...

  10. 转载 OKHttp使用详解

      一,OKHttp介绍 okhttp是一个第三方类库,用于android中请求网络. 这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso和Le ...