P9869题解
P9869 [NOIP2023] 三值逻辑
题解
T2 三值逻辑(tribool)
考察:模拟、图论(?)
我们拿个数组分别记录每个值在此刻与谁相等或与谁相反,特殊的,对于定值,多用 \(3\) 个变量记录,这是好模拟的。
然后操作结束后会得到若干初始值之间的相等与相反关系,考虑用无向有权图来刻画,那么由于每个点最多只贡献一条边,最终得到的是一个树与基环树的森林。
考虑对于每个联通块统计答案,容易发现,一个联通块要么全是 \(U\) 要么全不是 \(U\),所以:如果其中有 \(U\),那么只能算上贡献,否则除非迫不得已,我们一定不会赋 \(U\)。什么叫迫不得已?只有一种情况,就是基环树的环为奇环(奇环树(雾)),然后答案就是好统计的了。
但是细节很多,比如你基环树会找环吗?
我的代码相当丑:
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read() {
int s=0,m=0;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-')m=1;ch=getchar();}
while( isdigit(ch)) s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return m?-s:s;
}
int c,t,n,m,a[100005],fl[100005];
char op[5];int x,y;
int h[100005],cnt;
struct QWQ{int v,w,nxt;} e[100005*2];
void add(int u,int v,int w) {e[++cnt]={v,w,h[u]},h[u]=cnt;}
int vis[100005],num,ff,ans;
stack<int> st,wt;
void dfs(int u,int p,int ww) {
vis[u]=1;num++;
st.push(u);wt.push(ww);
for(int i=h[u];i;i=e[i].nxt) {
int v=e[i].v,w=e[i].w;
if(v==p) continue;
if(vis[v]&&ff==-1) {
ff=w;
while(st.size()&&st.top()!=v) {
ff^=wt.top();
st.pop();wt.pop();
}
}
if(!vis[v]) dfs(v,u,w);
}
if(ff==-1) st.pop(),wt.pop();
}
signed main() {
cin>>c>>t;
while(t--) {
n=read(),m=read();
for(int i=1;i<=n+3;i++) a[i]=i,fl[i]=0;
memset(h,0,sizeof(h));cnt=0;
memset(vis,0,sizeof(vis));
ans=0,num=0;
for(int i=1;i<=m;i++) {
scanf("%s%lld",op+1,&x);
switch(op[1]) {
case '+':y=read();a[x]=a[y],fl[x]=fl[y];break;
case '-':y=read();a[x]=a[y],fl[x]=fl[y]^1;break;
case 'T':a[x]=n+1,fl[x]=0;break;
case 'F':a[x]=n+2,fl[x]=0;break;
case 'U':a[x]=n+3,fl[x]=0;break;
}
}
for(int i=1;i<=n;i++)
add(i,a[i],fl[i]),add(a[i],i,fl[i]);
while(st.size()) st.pop(),wt.pop();ff=-1;
dfs(n+3,0,0);
ans+=num-1;
while(st.size()) st.pop(),wt.pop();ff=-1;
if(!vis[n+1]) dfs(n+1,0,0);
while(st.size()) st.pop(),wt.pop();ff=-1;
if(!vis[n+2]) dfs(n+2,0,0);
for(int i=1;i<=n;i++) {
if(!vis[i]) {
while(st.size()) st.pop(),wt.pop();ff=-1;
int las=num;
dfs(i,0,0);
if(ff==1) ans+=num-las;
}
}
printf("%lld\n",ans);
}
return 0;
}
时间复杂度 \(O(\sum n+m)\)。
本文来自博客园,作者:operator,转载请注明原文链接:https://www.cnblogs.com/operator-/p/17974778 ♪(^∀^●)ノシ

浙公网安备 33010602011771号