代码求调 P4426
  • 板块灌水区
  • 楼主As_Snow
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/1/28 21:41
  • 上次更新2024/1/29 08:05:27
查看原帖
代码求调 P4426
548999
As_Snow楼主2024/1/28 21:41

rt.

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
using mint=atcoder::modint998244353;
void Solve();
const int N = 2e5+25;
struct edge {
	int u,v;
	mint w[4];
	inline auto& operator[](unsigned x) { return w[x]; }
};
int n,m;
map<int,edge> e[N];
mint f[N][2];
int dag[N];
void addedge(int u,int v,mint a,mint b,mint c,mint d) {
	if(e[u].count(v)) {
		auto &w=e[u][v].w;
		w[0b00]*=a;
		w[0b01]*=b;
		w[0b10]*=c;
		w[0b11]*=d;
	} else {
		e[u][v]={u,v,{a,b,c,d}};
		++dag[u];
	}
}
void deledge(int u,int v) {
	if(e[u].count(v)) {
		e[u].erase(v);
		--dag[v];
	}
}
int q[N],hh,tt;
bool del[N];
int id[N],pos[N];
vector<edge> G;
signed main() {
	cin.tie(nullptr)->sync_with_stdio(false);
	Solve();
	return 0;
}
void Solve() {
	cin>>n>>m;
	for(int i=1;i<=m;i++) {
		int u,v; cin>>u>>v;
		addedge(u,v,1,1,1,0);
		addedge(v,u,1,1,1,0);
	}
	for(int i=1;i<=n;i++) f[i][0]=f[i][1]=1;
	hh=0,tt=0;
	for(int i=1;i<=n;i++) if(dag[i]<=2) q[tt++]=i;
	mint w[4];
	while(hh<tt) {
		int u=q[hh++];
		if(dag[u]==0||del[u]) continue;
		else if(dag[u]==1) {
			auto E=e[u].begin()->second;
			auto v=E.v;
			if(u>v) swap(E[0b01],E[0b10]);
			f[v][0]*=f[u][0]*E[0b00]+f[u][1]*E[0b10];
			f[v][1]*=f[u][0]*E[0b01]+f[u][1]*E[0b11];
			del[u]=true;
			deledge(u,v),deledge(v,u);
			if(dag[v]<=2) q[tt++]=v;
		} else if(dag[u]==2) {
			auto E1=e[u].begin()->second,E2=e[u].rbegin()->second;
			auto v1=E1.v,v2=E2.v;
			if(u>v1) swap(E1[0b01],E1[0b10]);
			if(u>v2) swap(E2[0b01],E2[0b10]);
			w[0b00]=f[u][0]*E1[0b00]*E2[0b00]+f[u][1]*E1[0b10]*E2[0b10];
			w[0b01]=f[u][0]*E1[0b00]*E2[0b01]+f[u][1]*E1[0b10]*E2[0b11];
			w[0b10]=f[u][0]*E1[0b01]*E2[0b00]+f[u][1]*E1[0b11]*E2[0b10];
			w[0b11]=f[u][0]*E1[0b01]*E2[0b01]+f[u][1]*E1[0b11]*E2[0b11];
			if(v1>v2) swap(w[0b01],w[0b10]);
			del[u]=true;
			deledge(u,v1),deledge(v1,u);
			deledge(u,v2),deledge(v2,u);
			addedge(v1,v2,w[0],w[1],w[2],w[3]);
			addedge(v2,v1,w[0],w[1],w[2],w[3]);
			if(dag[v1]<=2) q[tt++]=v1;
			if(dag[v2]<=2) q[tt++]=v2;
		}
		dag[u]=0;
	}
	m=0;
	for(int i=1;i<=n;i++) if(!del[i]) {
		pos[i]=m;
		id[m++]=i;
		for(const auto &it:e[i]) if(i<it.second.v) G.emplace_back(it.second);
	}
	n=m;
	mint ans=0;
	for(int s=0;s< 1<<n;s++) {
		mint cnt=1;
		for(int i=0;i<n;i++) if(s>>i&1)
			cnt*=f[id[i]][1];
		else cnt*=f[id[i]][0];
		for(const auto &E:G) {
			int p=s>>pos[E.u]&1,q=s>>pos[E.v]&1;
			cnt*=E.w[p<<1|q];
		}
		ans+=cnt;
	}
	printf("%d\n",ans.val());
}

modint998244353 是从 ACL 里粘的

2024/1/28 21:41
加载中...