結果

問題 No.2522 Fall in love, Girls!
コンテスト
ユーザー kazuppa
提出日時 2026-05-12 21:23:26
言語 C++23
(gcc 15.2.0 + boost 1.89.0)
コンパイル:
g++-15 -O2 -lm -std=c++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
RE  
実行時間 -
コード長 15,673 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 7,055 ms
コンパイル使用メモリ 435,968 KB
実行使用メモリ 126,568 KB
最終ジャッジ日時 2026-05-12 21:23:41
合計ジャッジ時間 11,279 ms
ジャッジサーバーID
(参考情報)
judge1_1 / judge3_1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 27 WA * 2 RE * 1
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
#include <chrono>
#include <complex>
#include <cmath>
#include <unistd.h>
#define pc_u putchar
#pragma GCC target ("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#define rep(i,a,b) for(it i=(it)(a);i<(it)b;i++)
#define rep2(i,a,b,c) for(it i=(it)(a);i<(it)b;i+=(it)c)
#define repp(i,a,b) for(it i=(it)(a);i<=(it)b;i++)
#define repp2(i,a,b,c) for(it i=(it)(a);i<=(it)b;i+=(it)c)
#define irep(i,a,b) for(int i=(int)(a);i<(int)b;i++)
#define irep2(i,a,b,c) for(int i=(int)(a);i<(int)b;i+=c)
#define irepp(i,a,b) for(int i=(int)(a);i<=(int)b;i++)
#define irepp2(i,a,b,c) for(int i=(int)(a);i<=(int)b;i+=c)
#define nrep(i,a,b) for(it i=(it)(a)-1;i>=(it)b;i--)
#define nrepp(i,a,b) for(it i=(it)(a);i>=(it)b;i--)
#define inrep(i,a,b) for(int i=(int)(a)-1;i>=(int)b;i--)
#define inrepp(i,a,b) for(int i=(int)(a);i>=(int)b;i--)
#define inrep2(i,a,b,c) for(int i=(int)(a)-1;i>=(int)b;i-=c)
#define inrepp2(i,a,b,c) for(int i=(int)(a);i>=(int)b;i-=c)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define Min(x) *min_element(all(x))
#define Max(x) *max_element(all(x))
#define popcount(x) __builtin_popcountll(x)
#define moda 998244353LL
#define modb 1000000007LL
#define modc 968244353LL
#define dai 2502502502502502502LL
#define sho -dai
#define aoi 1e18+1e6
#define giri 1010000000
#define en (db)3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
#define eps 1e-14
#define elif else if
template<typename T> using pq=priority_queue<T>;
template<typename T> using pqg=priority_queue<T,vector<T>,greater<T>>;
#define uni(a) a.erase(unique(all(a)),a.end())
using it=long long;
using itn=int;
using un=unsigned long long;
using idb=double;
using db=long double;
using st=string;
using ch=char;
using bo=bool;
using P=pair<it,it>;
using ip=pair<int,int>;
using vi=vector<it>;
using ivi=vector<int>;
using ivd=vector<idb>;
using vd=vector<db>;
using vs=vector<st>;
using vc=vector<ch>;
using vb=vector<bo>;
using vp=vector<P>;
using ivp=vector<ip>;
using sp=set<P>;
using isp=set<ip>;
using ss=set<st>;
using sca=set<ch>;
using si=set<it>;
using isi=set<int>;
using svi=set<vi>;
using svb=set<vb>;
using vvi=vector<vi>;
using ivvi=vector<ivi>;
using ivvd=vector<ivd>;
using vvd=vector<vd>;
using vvs=vector<vs>;
using vvb=vector<vb>;
using vvc=vector<vc>;
using vvp=vector<vp>;
using ivvp=vector<ivp>;
using vsi=vector<si>;
using ivsi=vector<isi>;
using isvi=set<ivi>;
using vsc=vector<sca>;
using vsp=vector<sp>;
using ivsp=vector<isp>;
using vvsi=vector<vsi>;
using ivvsi=vector<ivsi>;
using vvsp=vector<vsp>;
using ivvsp=vector<ivsp>;
using svvb=set<vvb>;
using vvvi=vector<vvi>;
using ivvvi=vector<ivvi>;
using ivvvd=vector<ivvd>;
using vvvd=vector<vvd>;
using vvvb=vector<vvb>;
using ivvvp=vector<ivvp>;
using vvvp=vector<vvp>;
using isvvi=set<ivvi>;
using vvvvi=vector<vvvi>;
using ivvvvi=vector<ivvvi>;
using vvvvd=vector<vvvd>;
using vvvvb=vector<vvvb>;
using ivvvvp=vector<ivvvp>;
using vvvvp=vector<vvvp>;
using ivvvvvi=vector<ivvvvi>;
using vvvvvi=vector<vvvvi>;
using ivvvvvvi=vector<ivvvvvi>;
using vvvvvd=vector<vvvvd>;
using vvvvvvi=vector<vvvvvi>;
using ivvvvvvvi=vector<ivvvvvvi>;
using vvvvvvd=vector<vvvvvd>;
using vvvvvvvi=vector<vvvvvvi>;
using vvvvvvvvi=vector<vvvvvvvi>;
st abc="abcdefghijklmnopqrstuvwxyz";
st ABC="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
st num="0123456789";
st mb="xo";
st MB="XO";
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template<class T> using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;

namespace {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  int s = (int)v.size();
  for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
  return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &x : v) is >> x;
  return is;
}

istream &operator>>(istream &is, __int128_t &x) {
  string S;
  is >> S;
  x = 0;
  int flag = 0;
  for (auto &c : S) {
    if (c == '-') {
      flag = true;
      continue;
    }
    x *= 10;
    x += c - '0';
  }
  if (flag) x = -x;
  return is;
}

istream &operator>>(istream &is, __uint128_t &x) {
  string S;
  is >> S;
  x = 0;
  for (auto &c : S) {
    x *= 10;
    x += c - '0';
  }
  return is;
}

ostream &operator<<(ostream &os, __int128_t x) {
  if (x == 0) return os << 0;
  if (x < 0) os << '-', x = -x;
  string S;
  while (x) S.push_back('0' + x % 10), x /= 10;
  reverse(begin(S), end(S));
  return os << S;
}
ostream &operator<<(ostream &os, __uint128_t x) {
  if (x == 0) return os << 0;
  string S;
  while (x) S.push_back('0' + x % 10), x /= 10;
  reverse(begin(S), end(S));
  return os << S;
}

void input() {}
template <typename T, class... U>
void input(T &t, U &...u) {
  cin >> t;
  input(u...);
}
template <typename T, class... U>
void input1(T &t, U &...u) {
  input(u...);
}
void print() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void print(const T &t, const U &...u) {
  cout << t;
  if (sizeof...(u)) cout << sep;
  print(u...);
}
template <typename T, class... U, char sep = ' '>
void print1(const T &t, const U &...u) {
  print(u...);
}

struct IoSetupNya {
  IoSetupNya() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(30);
    cerr << fixed << setprecision(7);
  }
} iosetupnya;

}  //namespace Nyaan

template<typename T>
T Sum(vector<T> &a){
  T s=0;
  for(auto i:a)s+=i;
  return s;
}

template<typename T>
T Sum(vector<T> &a,int l,int r){
  T s=0;
  irep(i,l,r)s+=a[i];
  return s;
}

template <typename T>
void dec(vector<T> &t,T k=1){
  for(auto &i:t)i-=k;
}

template <typename T>
void inc(vector<T> &t,T k=1){
  for(auto &i:t)i+=k;
}

template <typename T>
vector<T> make_vec(int n,T t){
  vector<T> g(n);
  for(auto &i:g)i=t;
  return g;
}

template <typename T>
vector<T> subvec(vector<T> a,int f,int l){
  vector<T> g(l);
  irep(i,f,f+l)g[i-f]=a[i];
  return g;
}

template<typename T>
vector<T> sorted(vector<T> a){
  sort(all(a));
  return a;
}

template<typename T>
int lod(vector<T> &a,T k){
  auto d=lower_bound(all(a),k);
  int e=distance(a.begin(),d);
  return e;
}

template<typename T>
void za(vector<T> &a){
  int n=a.size();
  map<T,int> atu;
  irep(i,0,n)atu[a[i]]=0;
  int ima=0;
  for(auto i:atu){
    atu[i.first]=ima;
    ima++;
  }
  irep(i,0,n)a[i]=atu[a[i]];
}

template<typename T>
T gcda(T a,T b){
  if(!a||!b)return max(a,b);
  if(a<0)a=-a;
  if(b<0)b=-b;
  while(a%b&&b%a){
    if(a>b)a%=b;
    else b%=a;
  }
  return min(a,b);
}

template<typename T>
T lcma(T a,T b){
  return a/gcda(a,b)*b;
}

template<typename T>
T isqrt(T n){
  T u=sqrt(n);
  while((u+1)*(u+1)<=n)u++;
  while(u*u>n)u--;
  return u;
}

db distance(db a,db b,db c,db d){return sqrt((a-c)*(a-c)+(b-d)*(b-d));}

db getAngle(db xa, db ya, db xb, db yb, db xc, db yc) {
  //角BACを求める
  //E8さんの記事コピペ
  db VectorAB = sqrt((xb - xa) * (xb - xa) + (yb - ya) * (yb - ya));
  db VectorAC = sqrt((xc - xa) * (xc - xa) + (yc - ya) * (yc - ya));
  db Naiseki = (xb - xa) * (xc - xa) + (yb - ya) * (yc - ya);
  db cosTheta = Naiseki / (VectorAB * VectorAC);
  return acos(cosTheta) * 180.0 / 3.14159265358979;
}

long double segment_origin_dist(long double A, long double B, long double C, long double D) {
    // P = (A,B), Q = (C,D)
    long double vx = C - A, vy = D - B; // ベクトルPQ
    long double wx = -A, wy = -B;       // ベクトルPO (O-P)

    long double vv = vx * vx + vy * vy; // |PQ|^2
    if (vv == 0) {
        // P == Q の場合、点と原点の距離
        return sqrt(A * A + B * B);
    }

    long double t = (wx * vx + wy * vy) / vv; // 射影パラメータ

    long double nx, ny; // 最近点
    if (t <= 0) {
        nx = A; ny = B;
    } else if (t >= 1) {
        nx = C; ny = D;
    } else {
        nx = A + t * vx;
        ny = B + t * vy;
    }

    return sqrt(nx * nx + ny * ny);
}

bo outc(int n,int x){
  return (x<0||x>=n);
}

bo outc(int h,int w,int x,int y){
  return (x<0||x>=h||y<0||y>=w);
}

template<typename T>
vector<vector<T>> nep(vector<T> a){
  vector<vector<T>> e;
  sort(all(a));
  do{
    e.emplace_back(a);
  }while(next_permutation(all(a)));
  return e;
}

template<typename T>
void chmin(T &a,T b){if(a>b)a=move(b);}
template<typename T>
void chmax(T &a,T b){if(a<b)a=move(b);}

void yn(bo a){print(a?string("Yes"):string("No"));}
void YN(bo a){print(a?string("YES"):string("NO"));}

int nCkMOD=moda;
vector<long long> fact, fact_inv, inv;
/*  init_nCk :二項係数のための前処理
    計算量:O(n)
*/
void init_nCk(int SIZE){
  fact.resize(SIZE+5);
  fact_inv.resize(SIZE+5);
  inv.resize(SIZE+5);
  fact[0]=fact[1]=1;
  fact_inv[0]=fact_inv[1]=1;
  inv[1]=1;
  irepp(i,2,SIZE+4){
    fact[i]=fact[i-1]*i%nCkMOD;
    inv[i]=nCkMOD-inv[nCkMOD%i]*(nCkMOD/i)%nCkMOD;
    fact_inv[i]=fact_inv[i-1]*inv[i]%nCkMOD;
  }
}
/*  nCk :MODでの二項係数を求める(前処理 int_nCk が必要)
    計算量:O(1)
*/
it nCk(int n, int k){
  if(n<k)return 0;
  if((n<0||k<0))return 0;
  return fact[n]*(fact_inv[k]*fact_inv[n-k]%nCkMOD)%nCkMOD;
}

int log2(it n){
  int l=0,r=63;
  while(r-l>1){
    int m=(l+r)/2;
    if(n>=(1LL<<m))l=m;
    else r=m;
  }
  return l;
}

it mod_pow(it x,it n,it mo){
  x%=mo;
  __int128_t res=1,e=x;
  while(n>0){
    if(n&1)res=res*e%mo;
    e=e*e%mo;
    n>>=1;
  }
  return res;
}

random_device seed_gen;
mt19937_64 engine(seed_gen());
ll randint(ll l,ll r){return l+engine()%(r-l);}

bo prime_checker(it n){
  if(n==2)return 1;
  if(n==1||!(n&1))return 0;
  it s=0;
  while(((n-1>>s+1)<<s+1)==n-1)s++;
  it d=(n-1>>s);
  vi A={2,3,5,7,11,13,17,19,23};
  for(it a:A){
    if(a==n)return 1;
    if(a>n)break;
    __int128_t r=mod_pow(a,d,n);
    if(r==1)continue;
    bo ok=1;
    irep(i,0,s){
      if(r==n-1){
        ok=0;
        break;
      }
      r=(r*r)%n;
    }
    if(ok)return 0;
  }
  return 1;
}

__int128_t fact_f(__int128_t x,__int128_t n,__int128_t c){return (x*x+c)%n;}
vi factrize(it N){
  if(!(N&(N-1))){
    vi x;
    while(N!=1){
      x.emplace_back(2);
      N/=2;
    }
    return x;
  }
  __int128_t n=N;
  if(n==1)return vi{};
  if(prime_checker(N))return vi{N};
  irep(p,0,1000){
    __int128_t x=randint(0,n),y=x,c=randint(1,n);
    rep(i,1,35000){
      x=fact_f(x,n,c),y=fact_f(fact_f(y,n,c),n,c);
      __int128_t d=gcda(abs((it)x-(it)y),N);
      if(d==n)break;
      if(d!=1){
        vi l=factrize(d),r=factrize(N/d);
        vi x;int u=0,v=0;
        while(u!=l.size()||v!=r.size()){
          if(u!=l.size()&&(v==r.size()||l[u]<r[v]))x.emplace_back(l[u]),u++;
          else x.emplace_back(r[v]),v++;
        }
        return x;
      }
    }
  }
  return {N};
}

vp factrize(it n,bo c){
  vi p=factrize(n);
  vp g(1,{p[0],1});
  irep(i,1,p.size())
    if(p[i-1]==p[i])g.back().second++;
    else g.emplace_back(p[i],1);
  return g;
}

it primitive_root(it p){
  assert(prime_checker(p));
  vi x=factrize(p-1);uni(x);
  while(1){
    it a=randint(1,p);
    bo ok=1;
    for(it i:x)
      if(mod_pow(a,(p-1)/i,p)==1)ok=0;
    if(ok)return a;
  }
}

struct bridge_enumeration{
  private:
  int n,io=0,is=0,id=0,p=0;
  ivvp g;ivvi h;
  ivp e,b;
  ivi o,l,s;vb a;
  void dfs1(int u,int t=-1){
    o[u]=io,l[u]=io,io++;
    int c=0;bo p=0;
    for(auto v:g[u]){
      if(t==v.first)continue;
      if(o[v.first]==-1){
        c++;
        dfs1(v.first,u);
        chmin(l[u],l[v.first]);
        if(t!=-1&&o[u]<=l[v.first])p=1;
      }
      else{
        chmin(l[u],o[v.first]);
      }
    }
    if(t==-1&&c>=2)p=1;
    a[u]=p;
  }
  void dfs2(int u){
    s[u]=is;
    for(int v:h[u]){
      if(s[v]==-1){
        dfs2(v);
      }
    }
  }
  bo check(int u,int v){
    if(o[u]>o[v])swap(u,v);
    return o[u]<l[v];
  }
  public:
  bridge_enumeration(int N,int _p=1){
    p=_p;
    n=N;
    g.resize(n);
    h.resize(n);
  }
  void add_edge(int u,int v,bo p=1){
    g[u].emplace_back(v,id);
    e.emplace_back(u,v);
    if(p){
      g[v].emplace_back(u,id);
      e.emplace_back(v,u);
    }
    id++;
  }
  ivp bridge(){
    o.resize(n,-1);
    l.resize(n,-1);
    a.resize(n,0);
    io=0;
    irep(i,0,n)
      if(o[i]==-1)dfs1(i);
    b.clear();
    ivi u;
    irep(c,0,e.size()){
      auto i=e[c];
      if(check(i.first,i.second))u.emplace_back(c/(p+1));
      else h[i.first].emplace_back(i.second);
    }
    irep(i,0,u.size())
      if(!i||u[i-1]!=u[i]){
        if(!p)b.emplace_back(e[u[i]]);
        else b.emplace_back(min(e[u[i]*2],e[u[i]*2+1]));
      }
    sort(all(b));
    return b;
  }
  ivvi tee(){
    bridge();
    s.resize(n,-1);
    irep(i,0,n)
      if(s[i]==-1)dfs2(i),is++;
    ivvi b(is);
    irep(i,0,n)b[s[i]].emplace_back(i);
    return b;
  }
  ivi aps(){
    o.resize(n,-1);
    l.resize(n,-1);
    a.resize(n,0);
    io=0,is=0;
    irep(i,0,n)
      if(o[i]==-1)dfs1(i);
    ivi aps;
    irep(i,0,n)
      if(a[i])aps.emplace_back(i);
    return aps;
  }
};

#include <atcoder/all>
using namespace atcoder;
using mints=modint998244353;
using mint=modint;
using minto=modint1000000007;
using vm=vector<mint>;
using vms=vector<mints>;
using vmo=vector<minto>;
using vvm=vector<vm>;
using vvms=vector<vms>;
using vvmo=vector<vmo>;
using vvvm=vector<vvm>;
using vvvms=vector<vvms>;
using vvvmo=vector<vvmo>;
using vvvvm=vector<vvvm>;
using vvvvms=vector<vvvms>;
using vvvvmo=vector<vvvmo>;
using vvvvvm=vector<vvvvm>;
using vvvvvms=vector<vvvvms>;
using vvvvvmo=vector<vvvvmo>;
using vvvvvvm=vector<vvvvvm>;
using vvvvvvms=vector<vvvvvms>;
using vvvvvvmo=vector<vvvvvmo>;
using vvvvvvvms=vector<vvvvvvms>;
using vvvvvvvmo=vector<vvvvvvmo>;

/*総和をもとめるセグ木
struct nod{
  it val;
  nod(it v=0):val(v){}
};

nod op(nod a,nod b){return nod(a.val+b.val);}
nod e(){return nod(0);}

struct act{
  it a;
  act(it e=0):a(e){}
};

nod mapping(act f,nod x){return nod(f.a+x.val);}
act comp(act f,act g){return act(f.a+g.a);}
act id(){return act(0);}*/
//#define endl '\n'
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
const int dx[8]={0,1,0,-1,1,1,-1,-1};
const int dy[8]={1,0,-1,0,1,-1,1,-1};


void solve(){
  int n,m,k;input(n,m,k);
  if(!m){
    mints ans=1;
    irep(i,1,n+1)ans*=i;
    ans/=n;
    ans*=n-m;
    print(ans.val());
    return;
  }
  ivi u(k),v(k);
  irep(i,0,k)input(u[i],v[i]);
  dec(u),dec(v);
  vb s(n);
  for(int i:u)s[i]=1;
  for(int i:v)s[i]=1;
  ivi d;
  irep(i,0,n)
    if(s[i])d.emplace_back(i);
  int p=d.size();
  ivvi g(p);ivi h(p);
  irep(i,0,k)
    irep(a,0,p)irep(b,0,p)
      if(u[i]==d[a]&&v[i]==d[b])g[a].emplace_back(b),h[b]++;
  vvms dp(1<<p,vms(p));dp[0][0]=1;
  irep(i,0,p)
    if(!h[i])dp[1<<i][i]++;
  irep(u,1,1<<p)irep(l,0,p){
    if(!dp[u][l].val())continue;
    ivi c=h;
    irep(i,0,p){
      if(!(u&(1<<i)))continue;
      for(int j:g[i])c[j]--;
    }
    irep(i,0,p)
      if(!(u&(1<<i))&&!c[i])dp[u+(1<<i)][l]+=dp[u][l];
  }
  int a=n-m,b=m;
  irep(i,0,p)
    if(d[i]<m)b--;
    else a--;
  mints ans=0;
  irep(l,0,p){
    mints s=dp.back()[l],tl=0,tr=a;
    if(m<=d[l]){
      tl=1;
      irep(i,p,n)tl*=i;
    }
    tr=a;
    irep(i,p+1,n)tr*=i;
    ans+=s*(tl+tr);
  }
  print(ans.val());
}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  //mae();
  int t=1;//input(t);
  while(t--)solve();
}
0