提出 #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;
}





提出情報

提出日時
問題 D - Urban Planning
ユーザ hamayanhamayan
言語 C++ (GCC 9.2.1)
得点 700
コード長 5941 Byte
結果 AC
実行時間 164 ms
メモリ 101912 KiB

コンパイルエラー

./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
結果
AC × 3
AC × 37
セット名 テストケース
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