結果
問題 | No.1303 Inconvenient Kingdom |
ユーザー |
![]() |
提出日時 | 2020-11-28 00:09:01 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 7 ms / 3,000 ms |
コード長 | 9,829 bytes |
コンパイル時間 | 2,097 ms |
コンパイル使用メモリ | 149,556 KB |
最終ジャッジ日時 | 2025-01-16 08:46:02 |
ジャッジサーバーID (参考情報) |
judge3 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 34 |
ソースコード
#include <cstdio>#include <cstring>#include <iostream>#include <string>#include <cmath>#include <bitset>#include <vector>#include <map>#include <set>#include <queue>#include <deque>#include <algorithm>#include <complex>#include <unordered_map>#include <unordered_set>#include <random>#include <cassert>#include <fstream>#include <utility>#include <functional>#include <time.h>#include <stack>#include <array>#include <list>#define popcount __builtin_popcountusing namespace std;typedef long long ll;typedef pair<int, int> P;struct unionfind{vector<int> par, sz;unionfind() {}unionfind(int n):par(n), sz(n, 1){for(int i=0; i<n; i++) par[i]=i;}int find(int x){if(par[x]==x) return x;return par[x]=find(par[x]);}void unite(int x, int y){x=find(x); y=find(y);if(x==y) return;if(sz[x]>sz[y]) swap(x, y);par[x]=y;sz[y]+=sz[x];}bool same(int x, int y){return find(x)==find(y);}int size(int x){return sz[find(x)];}};template<int MOD>struct ModInt{int x;ModInt(): x(0){}ModInt(ll y): x(y>=0 ? y%MOD : (MOD-(-y)%MOD)%MOD){}ModInt &operator+=(const ModInt &p){if((x+=p.x)>=MOD) x-=MOD;return *this;}ModInt &operator-=(const ModInt &p){if((x+=MOD-p.x)>=MOD) x-=MOD;return *this;}ModInt &operator*=(const ModInt &p){x=(int)(1ll*x*p.x%MOD);return *this;}ModInt &operator/=(const ModInt &p){*this*=p.inv();return *this;}ModInt operator-() const{ return ModInt(-x);}ModInt operator+(const ModInt &p) const{ return ModInt(*this)+=p;}ModInt operator-(const ModInt &p) const{ return ModInt(*this)-=p;}ModInt operator*(const ModInt &p) const{ return ModInt(*this)*=p;}ModInt operator/(const ModInt &p) const{ return ModInt(*this)/=p;}bool operator==(const ModInt &p) const{ return x==p.x;}bool operator!=(const ModInt &p) const{ return x!=p.x;}ModInt pow(ll n) const{ModInt ret(1), p(x);while(n){if(n&1) ret*=p;p*=p;n>>=1;}return ret;}ModInt inv() const{return pow(MOD-2);}};const int MOD=998244353;using mint=ModInt<MOD>;template<typename T>struct Matrix{vector<vector<T>> a;Matrix(){}Matrix(size_t n, size_t m):a(n, vector<T>(m, T(0))){}Matrix(size_t n):Matrix(n, n){}Matrix(vector<vector<T>> a):a(a){}size_t height() const{return a.size();}size_t width() const{return a[0].size();}inline const vector<T> &operator[](size_t k) const{return a[k];}inline vector<T> &operator[](size_t k){return a[k];}static Matrix I(size_t n){Matrix mat(n);for(int i=0; i<n; i++) mat[i][i]=1;return mat;}Matrix &operator+=(const Matrix &b){size_t n=height(), m=width();for(int i=0; i<n; i++){for(int j=0; j<m; j++){(*this)[i][j]+=b[i][j];}}return (*this);}Matrix &operator-=(const Matrix &b){size_t n=height(), m=width();for(int i=0; i<n; i++){for(int j=0; j<m; j++){(*this)[i][j]-=b[i][j];}}return (*this);}Matrix &operator*=(const Matrix &b){size_t n=height(), m=width(), l=b.width();vector<vector<T>> c(n, vector<T>(l, 0));for(int i=0; i<n; i++){for(int j=0; j<l; j++){for(int k=0; k<m; k++){c[i][j]+=(*this)[i][k]*b[k][j];}}}a.swap(c);return (*this);}Matrix operator+(const Matrix &b) const{return (Matrix(*this)+=b);}Matrix operator-(const Matrix &b) const{return (Matrix(*this)-=b);}Matrix operator*(const Matrix &b) const{return (Matrix(*this)*=b);}Matrix pow(ll k) const{Matrix ap(a), ret=I(height());while(k){if(k&1) ret*=ap;ap*=ap;k>>=1;}return ret;}static pair<Matrix, Matrix> Gauss_Jordan(const Matrix &a, const Matrix &b){size_t n=a.height(), m=a.width(), l=b.width();Matrix c(n, m+l);for(int i=0; i<n; i++) for(int j=0; j<m; j++) c[i][j]=a[i][j];for(int i=0; i<n; i++) for(int j=0; j<l; j++) c[i][j+m]=b[i][j];int d=0;for(int i=0; i<m; i++){int p=-1;for(int j=d; j<n; j++){if(c[j][i]!=0){p=j; break;}}if(p==-1) continue;swap(c[p], c[d]);T invc=T(1)/c[d][i];for(int j=i; j<m+l; j++) c[d][j]*=invc;for(int j=0; j<n; j++){if(j==d) continue;T c0=c[j][i];for(int k=i; k<m+l; k++){c[j][k]-=c0*c[d][k];}}d++;}Matrix reta(n, m), retb(n, l);for(int i=0; i<n; i++) for(int j=0; j<m; j++) reta[i][j]=c[i][j];for(int i=0; i<n; i++) for(int j=0; j<l; j++) retb[i][j]=c[i][j+m];return make_pair(reta, retb);}static pair<vector<T>, vector<vector<T>>> linear_equations(const Matrix &a, const vector<T> &b){int n=a.height(), m=a.width();Matrix B(n, 1);for(int i=0; i<n; i++) B[i][0]=b[i];auto p=Gauss_Jordan(a, B);vector<int> myon(n,-1);vector<int> nuo(m, -1);for(int i=0; i<n; i++){bool allzero=1;for(int j=0; j<m; j++){if(p.first[i][j]!=0){allzero=0;myon[i]=j;nuo[j]=i;break;}}if(allzero && p.second[i][0]!=0){vector<T> retc;vector<vector<T>> retd;return make_pair(retc, retd);}}vector<T> c(m);vector<vector<T>> d;for(int i=0; i<m; i++){if(nuo[i]==-1){vector<T> v(m);v[i]=1;for(int j=0; j<n; j++){if(myon[j]!=-1) v[myon[j]]=-p.first[j][i];}d.push_back(v);}else{c[i]=p.second[nuo[i]][0];}}return make_pair(c, d);}Matrix inv() const{int n=height();Matrix b=I(n);auto p=Gauss_Jordan(*this, b);if(p.first[n-1][n-1]==0){Matrix ret(0);return ret;}return p.second;}int rank() const{int n=height(), m=width();Matrix b(n, 0);auto p=Gauss_Jordan(*this, b);for(int i=0; i<n; i++){bool allzero=1;for(int j=0; j<m; j++){if(p.first[i][j]!=0){allzero=0;break;}}if(allzero) return i;}return n;}T det() const{size_t n=height();Matrix A(a);T ret(1);for(int i=0; i<n; i++){int p=-1;for(int j=i; j<n; j++){if(A[j][i]!=T(0)){p=j; break;}}if(p==-1){return T(0);}if(p!=i) ret*=-T(1);swap(A[p], A[i]);ret*=A[i][i];T inva=T(1)/A[i][i];for(int j=i+1; j<n; j++){T a0=A[j][i];for(int k=i; k<n; k++){A[j][k]-=inva*a0*A[i][k];}}}return ret;}};using Mat=Matrix<mint>;struct P1{mint a, b;P1(mint a):a(a){}P1(mint a, mint b):a(a), b(b){}P1 &operator+=(const P1 &p){a+=p.a;b+=p.b;return *this;}P1 &operator-=(const P1 &p){a-=p.a;b-=p.b;return *this;}P1 &operator*=(const P1 &p){mint x=a*p.a, y=a*p.b+b*p.a;a=x, b=y;return *this;}P1 &operator/=(const P1 &p){*this*=p.inv();return *this;}P1 operator-() const{ return P1(-a, -b);}P1 operator+(const P1 &p) const{ return P1(*this)+=p;}P1 operator-(const P1 &p) const{ return P1(*this)-=p;}P1 operator*(const P1 &p) const{ return P1(*this)*=p;}P1 operator/(const P1 &p) const{ return P1(*this)/=p;}bool operator==(const P1 &p) const{ return a==p.a && b==p.b;}bool operator!=(const P1 &p) const{ return a!=p.a || b!=p.b;}P1 inv()const{mint a1=a.inv();return P1(a1, -b*a1*a1);}};int main(){int n, m; cin>>n>>m;unionfind uf(n);int a[100010], b[100010];for(int i=0; i<m; i++){int u, v; cin>>u>>v;u--; v--;a[i]=u, b[i]=v;uf.unite(u, v);}vector<int> v;for(int i=0; i<n; i++){if(uf.find(i)==i){v.push_back(uf.size(i));}}sort(v.begin(), v.end(), greater<int>());if(v.size()==1){cout<<0<<endl;}else{ll ans=0, s2=0;for(auto x:v){ans+=x;s2+=x*x;}ans=ans*ans-s2;ans-=2*v[0]*v[1];cout<<ans<<endl;}vector<int> w[101];for(int i=0; i<n; i++){w[uf.find(i)].push_back(i);}mint ans=1;if(v.size()==1){Matrix<P1> mat1(n-1);bool e[101][101]={};for(int i=0; i<m; i++){e[a[i]][b[i]]=1; e[b[i]][a[i]]=1;if(a[i]<n-1){mat1[a[i]][a[i]]+=P1(1, 0);}if(b[i]<n-1){mat1[b[i]][b[i]]+=P1(1, 0);}if(a[i]<n-1 && b[i]<n-1){mat1[a[i]][b[i]]-=P1(1, 0);mat1[b[i]][a[i]]-=P1(1, 0);}}for(int i=0; i<n; i++){for(int j=0; j<i; j++){if(e[i][j]) continue;if(i<n-1) mat1[i][i]+=P1(0, 1);if(j<n-1) mat1[j][j]+=P1(0, 1);if(i<n-1 && j<n-1){mat1[i][j]-=P1(0, 1);mat1[j][i]-=P1(0, 1);}}}P1 ansp=mat1.det();cout<<(ansp.a+ansp.b).x<<endl;return 0;}for(int i=0; i<n; i++){if(w[i].size()<=1) continue;int s=w[i].size();Mat mat(s-1);for(int j=0; j<m; j++){if(uf.find(a[j])!=i) continue;int p=lower_bound(w[i].begin(), w[i].end(), a[j])-w[i].begin();int q=lower_bound(w[i].begin(), w[i].end(), b[j])-w[i].begin();if(p<s-1){mat[p][p]+=1;}if(q<s-1){mat[q][q]+=1;}if(p<s-1 && q<s-1){mat[p][q]-=1;mat[q][p]-=1;}}ans*=mat.det();}if(v[0]>v[1]){int c=0;for(auto x:v) if(x==v[1]) c++;ans*=mint(c*v[0]*v[1]);}else{int c=0;for(auto x:v){if(x==v[0]) c++;}ans*=mint(c*(c-1)/2*v[0]*v[0]);}cout<<ans.x<<endl;return 0;}