比赛 模拟赛 评测结果 AAAAAAAAAAAAAA
题目名称 《图》 最终得分 100
用户昵称 梦那边的美好ET 运行时间 6.969 s
代码语言 C++ 内存使用 487.62 MiB
提交时间 2019-04-29 10:12:49
显示代码纯文本
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<vector>
#define maxn 1000010
#define inf 999999999
#define LL long long
using namespace std;
const LL mod=(LL)998244353;
int sum;
struct treap{
	int l,r;
	int z,s;
	int c,si;
}a[maxn*20];
int _new(int x){
	a[++sum].z=x;
	a[sum].s=rand();
	a[sum].c=a[sum].si=1;
	return sum;
}
void update(int p){
	a[p].si=a[a[p].l].si+a[a[p].r].si+a[p].c;
}
void build(int &root){
	root=_new(-inf);
	a[root].r=_new(inf);
	update(root);
	return;
}
void zig(int &p){
	int q=a[p].l;
	a[p].l=a[q].r,a[q].r=p,p=q;
	update(a[p].r),update(p);
	return;
}
void zag(int &p){
	int q=a[p].r;
	a[p].r=a[q].l,a[q].l=p,p=q;
	update(a[p].l),update(p);
	return;
}
void insert(int &p,int x){
	if(p==0){
		p=_new(x);
		return;
	}
	if(x==a[p].z){
		a[p].c++,update(p);
		return;
	}
	if(x<a[p].z){
		insert(a[p].l,x);
		if(a[p].s<a[a[p].l].s)zig(p);
	}
	else{
		insert(a[p].r,x);
		if(a[p].s<a[a[p].r].s)zag(p);
	}
	update(p);
	return;
}
int getnext(int root,int x){
	int ans=2;
	int p=root;
	while(p){
		if(a[p].z==x){
			if(a[p].r>0){
			    p=a[p].r;
			    while(a[p].l>0)p=a[p].l;
			    ans=p;
			}
			break;
		}
		if(a[p].z>x&&a[p].z<a[ans].z)ans=p;
		p=(x<a[p].z)?a[p].l:a[p].r;
	}
	return a[ans].z;
}
void remove(int &p,int x){
	if(p==0)return;
	if(x==a[p].z){
		if(a[p].c>1){
			a[p].c--,update(p);
			return;
		}
		if(a[p].l||a[p].r){
			if(a[p].r==0||a[a[p].l].s>a[a[p].r].s)zig(p),remove(a[p].r,x);
			else zag(p),remove(a[p].l,x);
			update(p);
		}
		else p=0;
		return;
	}
	(x<a[p].z)?remove(a[p].l,x):remove(a[p].r,x);
	update(p);
	return;
}
int n,m,a1,a2;
vector<int>b[maxn];
int fa[maxn],root[maxn];
int find(int x){return fa[x]=(fa[x]==x)?x:find(fa[x]);}
int solve(int x){return a[root[x]].si-2;}
LL ans=(LL)1,f[maxn];
int main(){
    freopen("graphh.in","r",stdin);
    freopen("graphh.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
    	scanf("%d%d",&a1,&a2);
    	b[a1].push_back(a2);
    	b[a2].push_back(a1);
    }
    for(int i=1;i<=n;i++)fa[i]=i,build(root[i]);
    for(int i=1;i<=n;i++){
    	int f1=find(i);
    	for(int j=0;j<b[i].size();j++){
    		int x=b[i][j],f2=find(b[i][j]);
    		if(x>i){
    			if(getnext(root[f1],x-1)!=x)insert(root[f1],x);
    		}
    		else{
    			if(f1==f2)continue;
				remove(root[f2],i);
				if(solve(f1)<solve(f2))swap(f1,f2);fa[f2]=f1;
				int y=-inf;
                if(solve(f2)>0)for(int k=1;k<=solve(f2);k++){
                	y=getnext(root[f2],y);
                	if(getnext(root[f1],y-1)!=y)insert(root[f1],y);
                }
    		}
    	}
    	f[i]=solve(find(i));
    }
    for(int i=n;i>=1;i--)ans=(ans*(LL)(n-f[i]))%mod;
    printf("%lld\n",ans);
    return 0;
}