diff --git a/src/10/25/P9869.cpp b/src/10/25/P9869.cpp new file mode 100644 index 0000000..539276b --- /dev/null +++ b/src/10/25/P9869.cpp @@ -0,0 +1,76 @@ +#include +#include +#include +using ll = int64_t; + +const ll maxn = 1e5+5; +const ll T=1e5+3,F=-1e5-3,U=0; +ll c,t,n,m,f[maxn]; +std::bitset<2*maxn> vis; +#define vis(x)vis[(x)+n] + +static inline ll find(ll x){ + ll ret; + if(x==T||x==F)ret=x; + else if(vis(-x)||x==U){ + ret=U; + }else if(vis(x))ret=T; + else if(x<0){ + if(-f[-x] == x)ret=x; + else{ + vis(x)=true; + f[-x]=ret=find(-f[-x]); + vis(x)=false; + } + }else{ + if(f[x]==x)ret=x; + else{ + vis(x)=true; + f[x]=ret=find(f[x]); + vis(x)=false; + } + } + return ret; +} + +static inline void solve(){ + vis.reset(); + std::cin>>n>>m; + ll ans=0; + for(ll i=1;i<=n;i++)f[i]=i; + for(ll i=1;i<=m;i++){ + char c; + std::cin>>c; + if(c=='T' || c=='F' || c=='U'){ + ll v; + std::cin>>v; + switch (c) { + case 'T':f[v]=T;break; + case 'F':f[v]=F;break; + case 'U':f[v]=U;break; + } + }else if(c=='+'){ + ll i,j; + std::cin>>i>>j; + f[i]=f[j]; + }else if(c=='-'){ + ll i,j; + std::cin>>i>>j; + f[i]=-f[j]; + } + } + for(ll i=1;i<=n;i++){ + ans+=find(i)==U; + } + std::cout<>c>>t; + while (t--) { + solve(); + } +} diff --git a/src/10/25/P9869t.cpp b/src/10/25/P9869t.cpp new file mode 100644 index 0000000..11e4ae0 --- /dev/null +++ b/src/10/25/P9869t.cpp @@ -0,0 +1,97 @@ +#include +#define int long long +using namespace std; + +// 定义三个特殊值来表示三值逻辑 +// 使用很大的数字来避免与普通变量下标冲突 +const int T = 100001, F = -100001, U = 0; // T代表True,F代表False,U代表Unknown + +int c, t, n, m, a, b, fa[100005]; // fa数组用于记录每个变量的当前值或依赖关系 +char ch[100005]; // 存储每条语句的操作类型 +bool book[300005]; // 标记数组,用于在递归查找时检测环 + +// 核心函数:查找变量x的最终逻辑值 +int find(int x) { + int re; // 返回值 + + // 情况1:如果x已经是基础值(T/F/U),直接返回 + if (x == T || x == F) re = x; + else if (book[n - x] || x == U) re = U; + // 这里book[n-x]是处理负数的标记,x==U表示已经是Unknown + + // 情况2:如果x被标记为True(在递归路径中) + else if (book[x + n]) re = T; + + // 情况3:处理负数(表示逻辑非操作的结果) + else if (x < 0) { + // 如果负数指向自己,说明形成了自环,保持原值 + if (x == -fa[-x]) re = x; + else { + book[x + n] = 1; // 标记当前节点,防止无限递归 + // 递归查找:¬(¬A) = A,所以这里取双重否定 + re = find(-fa[-x]); + book[x + n] = 0; // 回溯,清空标记 + } + } + + // 情况4:处理正数(普通变量引用) + else { + // 如果指向自己,说明是基础值或已确定的值 + if (x == fa[x]) re = x; + else { + book[x + n] = 1; // 标记当前节点 + // 递归查找依赖的值 + re = fa[x] = find(fa[x]); // 路径压缩 + book[x + n] = 0; // 回溯,清空标记 + } + } + return re; +} + +signed main() { + cin >> c >> t; // 读入测试点编号和数据组数 + + while (t--) { + cin >> n >> m; // 变量个数和语句条数 + + // 初始化:每个变量最初指向自己 + for (int i = 1; i <= n; i++) fa[i] = i; + + // 处理每条语句 + for (int i = 1; i <= m; i++) { + cin >> ch[i]; // 读入操作类型 + + if (ch[i] == 'T') { // 赋值为True + cin >> a; + fa[a] = T; // 直接标记为T + } + else if (ch[i] == 'F') { // 赋值为False + cin >> a; + fa[a] = F; // 直接标记为F + } + else if (ch[i] == 'U') { // 赋值为Unknown + cin >> a; + fa[a] = U; // 直接标记为U + } + else { + cin >> a >> b; + if (ch[i] == '+') { // 赋值操作:x_a ← x_b + fa[a] = fa[b]; // 直接复制值或引用 + } + else { // 取反操作:x_a ← ¬x_b + fa[a] = -fa[b]; // 用负数表示逻辑非 + // 例如:如果fa[b]=T(100001),那么fa[a]=-100001 + // 这表示"非True",在find函数中会特殊处理 + } + } + } + + int ans = 0; + // 统计最终值为Unknown的变量个数 + for (int i = 1; i <= n; i++) { + if (find(i) == U) ans++; + } + cout << ans << endl; + } + return 0; +} \ No newline at end of file