「2019纪中集训Day2」解题报告

T1、Attack

bzoj2674

这道题时间给的比较多 (可能是以前评测机比较弱)\(O(nm)\) 就可以过。

\(Sol\) 给了分块加划分树的做法,不是很会,但是这道题可以用很多数据结构来做;
我写了整体二分+树套树 (还没调出来),整体二分+ \(cdq\) 也行,代码应该是最短的。

只给出 \(O(nm)\) 的代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
int in() {
	int x = 0; char c = getchar(); bool f = 0;
	while (c < '0' || c > '9')
		f |= c == '-', c = getchar();
	while (c >= '0' && c <= '9')
		x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
	return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }

const int N = 6e4 + 5;

struct node {
	int x, y, z;
} a[N];

int n, m, id[N], rnk[N];

inline bool cmp(const int &i, const int &j) {
	return a[i].z < a[j].z;
}

char s[11];

int main() {
//	freopen("in", "r", stdin);
	n = in(), m = in();
	for (int i = 1; i <= n; ++i)
		a[i] = (node){in(), in(), in()}, id[i] = i;
	std::sort(id + 1, id + 1 + n, cmp);
	for (int i = 1; i <= n; ++i)
		rnk[id[i]] = i;
	while (m--) {
		scanf(" %s", s);
		if (s[0] == 'S') {
			int u = in() + 1, v = in() + 1;
			std::swap(a[u].z, a[v].z);
			std::swap(id[rnk[u]], id[rnk[v]]);
			std::swap(rnk[u], rnk[v]);
		} else {
			int x = in(), y = in(), p = in(), s = in(), k = in();
			if (!k) {
				puts("It doesn't exist.");
				continue;
			}
			if (x > p)
				std::swap(x, p);
			if (y > s)
				std::swap(y, s);
			for (int i = 1; i <= n; ++i) {
				if (a[id[i]].x >= x && a[id[i]].y >= y && a[id[i]].x <= p && a[id[i]].y <= s)
					--k;
				if (!k) {
					printf("%d\n", a[id[i]].z);
					break;
				}
			}
			if (k)
				puts("It doesn't exist.");
		}
	}
	return 0;
}

T2、Contra

bzoj2676

\(Sol\)
\(f[i + 1][min(j + 1,Q)][\min(k + 1, R)] += p \times f[i][j][k]\) (第 \(i +1\) 轮通过);
\(f[i + 1][j - 1][0] += (1 - p) \times f[i][j][k], (j > 1)\) (第 \(i + 1\) 轮不通过);
因为期望的线性性,可以单独计算每一轮游戏的贡献, \(ans = \sum {f[i][j][k] \times p \times \min(k + 1, R)}\),其中 \(f[i][j][k]\) 为合法状态。

因为合法状态数最多不超过 \(\frac{Q * (Q - 1)}{2} + R + 1\),所以可以矩阵优化。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
typedef double db;
int in() {
	int x = 0; char c = getchar(); bool f = 0;
	while (c < '0' || c > '9')
		f |= c == '-', c = getchar();
	while (c >= '0' && c <= '9')
		x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
	return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }

const int M = 45;
const db eps = 4e-8;

int n, r, q, s, nn;

struct matrix {
	db a[M][M];
	matrix(db t = 0) {
		memset(a, 0, sizeof(a));
		if (t > 0)
			for (int i = 1; i <= nn; ++i)
				a[i][i] = t;
	}
	inline db* operator [] (int x) {
		return a[x];
	}
	inline matrix operator * (matrix &b) const {
		matrix ret;
		for (int k = 1; k <= nn; ++k)
			for (int i = 1; i <= nn; ++i)
				for (int j = 1; j <= nn; ++j)
					ret[i][j] += a[i][k] * b[k][j];
		return ret;
	}
} ;

matrix qpow(matrix base, int b) {
	matrix ret(1);
	for (; b; b >>= 1, base = base * base)
		if (b & 1)
			ret = ret * base;
	return ret;
}

int state[7][21], cnt;
db calc(db p) {
	matrix a(0), trans(0);
	a[1][state[q][1]] = p, a[1][state[q - 1][0]] = 1 - p, a[1][nn] = p * std::min(1, r);
	trans[nn][nn] = 1;
	for (int j = 1; j <= q; ++j) {
		for (int k = 0; k <= r; ++k) {
			if (j != q && k >= j)
				continue;
			int x = std::min(q, j + 1), y = std::min(r, k + 1);
			trans[state[j][k]][state[x][y]] = p;
			trans[state[j][k]][state[j - 1][0]] = 1 - p;
			trans[state[j][k]][nn] = p * std::min(r, k + 1);
//			printf("%lf\n", trans[state[j][k]][nn]);
		}
	}
	trans = qpow(trans, n - 1);
	a = a * trans;
	return a[1][nn];
}

int main() {
//	freopen("in", "r", stdin);
	n = in(), r = in(), q = in(), s = in();
	for (int i = 1; i <= q; ++i)
		for (int j = 0; j <= r; ++j)
			if ((i == q) || (j < i))
				state[i][j] = ++nn;
	++nn;
	if (calc(1) - s < eps) {
		puts("Impossible.");
		return 0;
	}
	db l = 0, r = 1, mid;
	while (r - l > eps) {
		mid = (l + r) / 2;
		if (calc(mid) > s)
			r = mid;
		else
			l = mid + eps;
	}
	printf("%lf\n", l);
	return 0;
}

T3、Bomb

bzoj2675

最大值分类讨论,最小值分治即可 (也可以选择随机化分治)

posted @ 2019-08-03 17:04  15owzLy1  阅读(161)  评论(0编辑  收藏  举报