提出 #13928806
ソースコード 拡げる
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(x) (x).begin(),(x).end()
//#pragma GCC optimize ("-O3")
using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
//---------------------------------------------------------------------------------------------------
template<int MOD> struct ModInt {
static const int Mod = MOD; unsigned x; ModInt() : x(0) { }
ModInt(signed sig) { x = sig < 0 ? sig % MOD + MOD : sig % MOD; }
ModInt(signed long long sig) { x = sig < 0 ? sig % MOD + MOD : sig % MOD; }
int get() const { return (int)x; }
ModInt &operator+=(ModInt that) { if ((x += that.x) >= MOD) x -= MOD; return *this; }
ModInt &operator-=(ModInt that) { if ((x += MOD - that.x) >= MOD) x -= MOD; return *this; }
ModInt &operator*=(ModInt that) { x = (unsigned long long)x * that.x % MOD; return *this; }
ModInt &operator/=(ModInt that) { return *this *= that.inverse(); }
ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
ModInt operator/(ModInt that) const { return ModInt(*this) /= that; }
ModInt inverse() const { long long a = x, b = MOD, u = 1, v = 0;
while (b) { long long t = a / b; a -= t * b; std::swap(a, b); u -= t * v; std::swap(u, v); }
return ModInt(u); }
bool operator==(ModInt that) const { return x == that.x; }
bool operator!=(ModInt that) const { return x != that.x; }
ModInt operator-() const { ModInt t; t.x = x == 0 ? 0 : Mod - x; return t; }
};
template<int MOD> ostream& operator<<(ostream& st, const ModInt<MOD> a) { st << a.get(); return st; };
template<int MOD> ModInt<MOD> operator^(ModInt<MOD> a, unsigned long long k) {
ModInt<MOD> r = 1; while (k) { if (k & 1) r *= a; a *= a; k >>= 1; } return r; }
template<typename T, int FAC_MAX> struct Comb { vector<T> fac, ifac;
Comb(){fac.resize(FAC_MAX,1);ifac.resize(FAC_MAX,1);rep(i,1,FAC_MAX)fac[i]=fac[i-1]*i;
ifac[FAC_MAX-1]=T(1)/fac[FAC_MAX-1];rrep(i,FAC_MAX-2,1)ifac[i]=ifac[i+1]*T(i+1);}
T aPb(int a, int b) { if (b < 0 || a < b) return T(0); return fac[a] * ifac[a - b]; }
T aCb(int a, int b) { if (b < 0 || a < b) return T(0); return fac[a] * ifac[a - b] * ifac[b]; }
T nHk(int n, int k) { if (n == 0 && k == 0) return T(1); if (n <= 0 || k < 0) return 0;
return aCb(n + k - 1, k); } // nHk = (n+k-1)Ck : n is separator
T pairCombination(int n) {if(n%2==1)return T(0);return fac[n]*ifac[n/2]/(T(2)^(n/2));}
// combination of paris for n
};
typedef ModInt<1000000007> mint;
struct UnionFind {
using T = int;
const T def = 0;
T f(T a, T b) { return a + b; }
//==========================================
vector<int> par;
vector<T> value;
UnionFind() {}
UnionFind(int NV) { init(NV); }
void init(int NV) { par.clear(); rep(i, 0, NV) par.push_back(i); value.resize(NV, 1); }
void reset() { rep(i, 0, par.size()) par[i] = i; }
int operator[](int x) {
if (par[x] == x) return x;
else {
int res = operator[](par[x]);
if (res != par[x]) {
value[res] = f(value[res], value[par[x]]);
value[par[x]] = def;
}
return par[x] = res;
}
}
// uf(x,y)->y
void operator()(int x, int y) {
x = operator[](x); y = operator[](y);
if (x != y) {
value[y] += value[par[x]];
value[par[x]] = def;
par[x] = y;
}
}
T getValues(int x) { return value[operator[](x)]; };
};
/*---------------------------------------------------------------------------------------------------
∧_∧
∧_∧ (´<_` ) Welcome to My Coding Space!
( ´_ゝ`) / ⌒i @hamayanhamayan0
/ \ | |
/ / ̄ ̄ ̄ ̄/ |
__(__ニつ/ _/ .| .|____
\/____/ (u ⊃
---------------------------------------------------------------------------------------------------*/
int N, P[5010], K;
vector<int> gr;
//---------------------------------------------------------------------------------------------------
int cycle_num = 0;
bool pending[5010];
void unite() {
UnionFind uf(N);
int K = 0;
rep(i, 0, N) {
if (0 <= P[i]) {
int x = i;
int y = P[i];
if (uf[x] != uf[y]) {
uf(x, y);
}
else cycle_num++;
}
else K++;
}
rep(i, 0, N) if (P[i] < 0) pending[uf[i]] = true;
rep(i, 0, N) if (i == uf[i] && pending[i]) gr.push_back(uf.getValues(i));
}
//---------------------------------------------------------------------------------------------------
Comb<mint, 10101> com;
mint dp[5010][5010];
bool vis[5010][5010];
mint calc() {
dp[0][0] = 1;
rep(i, 0, K) rep(len, 0, K) {
dp[i + 1][len] += dp[i][len];
dp[i + 1][len + 1] += dp[i][len] * gr[i];
}
mint res = 0;
// cycle 1
rep(i, 0, K) res += mint(gr[i] - 1) * (mint(N - 1) ^ (K - 1));
// cycle greater than 1
rep(len, 2, K + 1) res += dp[K][len] * com.fac[len - 1] * (mint(N - 1) ^ (K - len));
return res;
}
//---------------------------------------------------------------------------------------------------
void _main() {
cin >> N;
rep(i, 0, N) {
cin >> P[i], P[i]--;
if (P[i] < 0) K++;
}
unite();
mint ans = mint(N - cycle_num) * (mint(N - 1) ^ K);
ans -= calc();
cout << ans << endl;
}
提出情報
コンパイルエラー
./Main.cpp: In member function ‘void UnionFind::reset()’:
./Main.cpp:2:33: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<int>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
2 | #define rep(i,a,b) for(int i=a;i<b;i++)
......
56 | void reset() { rep(i, 0, par.size()) par[i] = i; }
| ~~~~~~~~~~~~~~~~
./Main.cpp:56:17: note: in expansion of macro ‘rep’
56 | void reset() { rep(i, 0, par.size()) par[i] = i; }
| ^~~
ジャッジ結果
| セット名 |
Sample |
All |
| 得点 / 配点 |
0 / 0 |
700 / 700 |
| 結果 |
|
|
| セット名 |
テストケース |
| Sample |
s1.txt, s2.txt, s3.txt |
| All |
01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, 24.txt, 25.txt, 26.txt, 27.txt, 28.txt, 29.txt, 30.txt, 31.txt, 32.txt, 33.txt, 34.txt, s1.txt, s2.txt, s3.txt |
| ケース名 |
結果 |
実行時間 |
メモリ |
| 01.txt |
AC |
65 ms |
101744 KiB |
| 02.txt |
AC |
61 ms |
101748 KiB |
| 03.txt |
AC |
61 ms |
101744 KiB |
| 04.txt |
AC |
64 ms |
101708 KiB |
| 05.txt |
AC |
66 ms |
101716 KiB |
| 06.txt |
AC |
61 ms |
101644 KiB |
| 07.txt |
AC |
61 ms |
101700 KiB |
| 08.txt |
AC |
63 ms |
101728 KiB |
| 09.txt |
AC |
61 ms |
101712 KiB |
| 10.txt |
AC |
61 ms |
101788 KiB |
| 11.txt |
AC |
62 ms |
101712 KiB |
| 12.txt |
AC |
62 ms |
101792 KiB |
| 13.txt |
AC |
61 ms |
101712 KiB |
| 14.txt |
AC |
64 ms |
101720 KiB |
| 15.txt |
AC |
62 ms |
101728 KiB |
| 16.txt |
AC |
159 ms |
101908 KiB |
| 17.txt |
AC |
161 ms |
101752 KiB |
| 18.txt |
AC |
164 ms |
101856 KiB |
| 19.txt |
AC |
88 ms |
101732 KiB |
| 20.txt |
AC |
102 ms |
101744 KiB |
| 21.txt |
AC |
116 ms |
101744 KiB |
| 22.txt |
AC |
124 ms |
101880 KiB |
| 23.txt |
AC |
132 ms |
101912 KiB |
| 24.txt |
AC |
134 ms |
101768 KiB |
| 25.txt |
AC |
140 ms |
101824 KiB |
| 26.txt |
AC |
91 ms |
101696 KiB |
| 27.txt |
AC |
76 ms |
101728 KiB |
| 28.txt |
AC |
113 ms |
101892 KiB |
| 29.txt |
AC |
71 ms |
101788 KiB |
| 30.txt |
AC |
73 ms |
101740 KiB |
| 31.txt |
AC |
76 ms |
101712 KiB |
| 32.txt |
AC |
109 ms |
101820 KiB |
| 33.txt |
AC |
109 ms |
101812 KiB |
| 34.txt |
AC |
92 ms |
101804 KiB |
| s1.txt |
AC |
59 ms |
101628 KiB |
| s2.txt |
AC |
61 ms |
101580 KiB |
| s3.txt |
AC |
64 ms |
101704 KiB |