1. 程式人生 > >SRM 733 Div 1 爆零記

SRM 733 Div 1 爆零記

using eas long 記錄 bits med back n-2 fab

開場寫easy(有預感要FST)

然後medium就卡住了。

我只知道$n$個點的生成樹個數是$n^{n-2}$

接下來直接狗帶……

$Problem 250pts$

水題,直接枚舉然後記錄答案(我大概是因為精度問題被HACK了)

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)
#define MP		make_pair
#define fi		first
#define se		second

typedef long long LL;
typedef pair <int, int> PII;
typedef pair <PII, PII> PIIII;

const double eps = 1e-12;

class MinimizeAbsoluteDifferenceDiv1 {
	public:
		vector<int> findTuple(vector<int> x) {

			PIIII ans = MP(MP(1e9, 1e9), MP(1e9, 1e9));

			double ff = 1e9;
			rep(i, 0, 4){
				rep(j, 0, 4){
					if (i == j) continue;
					rep(k, 0, 4){
						if (k == i || k == j) continue;
						rep(l, 0, 4){
							if (l == i || l == j || l == k) continue;
							double aa = fabs(1.00 * x[i] / x[j] - 1.00 * x[k] / x[l]);

							if (aa < ff - eps){
								ff = aa;
								ans = MP(MP(i, j), MP(k, l));
							}
						}
					}
				}
			}

			vector <int>  ret;
			ret.push_back(ans.fi.fi);
			ret.push_back(ans.fi.se);
			ret.push_back(ans.se.fi);
			ret.push_back(ans.se.se);
			return ret;
		}
};

$Problem 500Pts$

給定一個邊集,求符合條件的生成樹的個數(生成樹的邊必須包含這個邊集,點數 <= $1000$)

比賽的時候差一點就推出公式樂……不知道為什麽

設連通塊個數為$s$,每個連通塊的點數的乘積為$m$,

那麽答案為$mn^{s-2}$

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)
#define MP		make_pair
#define fi		first
#define se		second

typedef long long LL;

const int N = 1e3 + 10;
const LL mod = 987654323;

class BuildingSpanningTreesDiv1 {
	public:

		int father[N], c[N];

		inline LL Pow(LL a, LL b, LL mod){
			LL ret(1);
			for (; b; b >>= 1, (a *= a) %= mod) if (b & 1) (ret *= a) %= mod;
			return ret;
		}

		int getfather(int x){
			return father[x] ? father[x] = getfather(father[x]) : x;
		}

		int getNumberOfSpanningTrees(int n, vector <int> a, vector <int> b) {
			int m = (int)a.size();

			memset(father, 0, sizeof father);

			int block = n;
			rep(i, 0, m - 1){
				int x = a[i], y = b[i];
				int fx = getfather(x), fy = getfather(y);
				if (fx == fy) return 0;

				--block;
				father[fx] = fy;
			}

			memset(c, 0, sizeof c);
			rep(i, 1, n){
				int x = getfather(i);
				++c[x];
			}

			vector <LL> v;
			rep(i, 1, n) if (c[i]) v.push_back(c[i]);

			if (block == 1) return 1;
			LL ans = Pow((LL)n, (LL)block - 2, mod);
			for (auto u : v) ans = ans * u % mod;
			return (int)ans;
		}
};

SRM 733 Div 1 爆零記