比赛 |
模拟赛 |
评测结果 |
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;
}