【2021夏紀中游記】2021.8.12模擬賽

比賽歸納:

\(\mathrm{sum}=100+50+80\)html

個人 AK 啊嗚嗚嗚嗚。spa

T1 【NOIP2016提升A組模擬9.2】積木:

題目大意:

每秒中有必定的機率浮現幻象,持續 \(x\) 秒的幻象將產生 \(x^2\) 的幻象值。在 \(N\) 秒內指望產生的幻象值是多少。code

思路:

麻了,原題htm

T2 【NOIP2016提升A組模擬9.4】樹上摩托:

題目大意:

把樹去掉任意條邊,拆成若干棵新樹,求讓每棵新樹的節點數相同的方案數。blog

思路:

兩個性質:ip

  1. 只要新樹大小能整除於以當前結點爲根的樹的大小可以,他就能夠拆。
  2. 對於每一種新樹大小,它只能有一個方案。

代碼:

紀中機子平常爆棧。get

const int N = 1e6 + 10;

inline ll Read()
{
	ll x = 0, f = 1;
	char c = getchar();
	while (c != '-' && (c < '0' || c > '9')) c = getchar();
	if (c == '-') f = -f, c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return x * f;
}

int n;
int head[N], tot;
struct edge
{
	int to, nxt;
}e[N << 1];

void add(int u, int v)
{
	e[++tot] = (edge){v, head[u]}, head[u] = tot;
}

int siz[N], fa[N];
int q[N], H, T;
inline void bfs(int s)
{
	H = 1, T = 0;
	q[++T] = s;
	fa[1] = 0;
	while(H <= T)
	{
		int u = q[H++];
		siz[u] = 1;
		for (int i = head[u]; i; i = e[i].nxt)
		{
			int v = e[i].to;
			if (~fa[v]) continue;
			fa[v] = u;
			q[++T] = v;
		}
	} 
	for (int i = T; i; i--)
	{
		int u = fa[q[i]], v = q[i];
		siz[u] += siz[v];
	}
}

int ans;

int main()
{
	memset(fa, -1, sizeof fa);
	n = Read();
	for (int i = 1; i < n; i++)
	{
		int u = Read(), v = Read();
		add(u, v), add(v, u);
	}
	bfs(1);
	for (int i = 1; i * i <= n; i++)
	{
		if (n % i) continue;
		int cnt1 = 0, cnt2 = 0;
		for (int j = 1; j <= n; j++)
			cnt1 += siz[j] % i == 0,
			cnt2 += siz[j] % (n / i) == 0;
		ans += (cnt1 == n / i) + (cnt2 == i);
		if(i * i == n) ans--;
	}
	printf ("%d\n", ans);
	return 0;
}

T3 【GDOI2017模擬9.4】矩陣:

題目大意:

思路:

先用把 \(\mathrm{mina}\times\mathrm{minb}\) 的子矩陣所有存進堆裏。而後每次取出最優的,並把其向右向下延申的矩陣再存進堆。相同的矩陣用 hash 維護。hash

這個找第 \(k\) 大(小)的想法很像【Luogu P2048】[NOI2010] 超級鋼琴【Luogu P5283】[十二省聯考2019]異或糉子it

代碼:

#define num(i,j) (i-1) * m + j

inline ll Read()
{
	ll x = 0, f = 1;
	char c = getchar();
	while (c != '-' && (c < '0' || c > '9')) c = getchar();
	if (c == '-') f = -f, c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return x * f;
}

int n, m, mina, minb, k;
ll sum[N][N];

struct Matrix
{
	int x1, y1, x2, y2; ll val;
	Matrix(int X1, int Y1, int X2, int Y2)
	{
		x1 = X1, y1 = Y1, x2 = X2, y2 = Y2;
		val = sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
	}
	bool operator < (const Matrix &a) const
	{
		return val > a.val;
	}
};

priority_queue<Matrix> q;
map<pair<int, int>, int> hash;

int main()
{
	n = Read(), m = Read(), mina = Read(), minb = Read(), k = Read();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + Read();
	
	for (int i = mina; i <= n; i++)
		for (int j = minb; j <= m; j++)
			q.push(Matrix(i - mina + 1, j - minb + 1, i, j));
	
	for (int i = 1; i < k; i++)
	{
		if (q.empty())
		{
			puts("-1");
			return 0;
		}
		Matrix tmp = q.top(); q.pop();
		int x1 = tmp.x1, y1 = tmp.y1, x2 = tmp.x2, y2 = tmp.y2;
		if(x2 < n && !hash[make_pair(num(x1, y1), num(x2 + 1, y2))]) 
			q.push(Matrix(x1, y1, x2 + 1, y2)),
			hash[make_pair(num(x1, y1), num(x2 + 1, y2))] = 1;
			
		if(y2 < m && !hash[make_pair(num(x1, y1), num(x2, y2 + 1))]) 
			q.push(Matrix(x1, y1, x2, y2 + 1)),
			hash[make_pair(num(x1, y1), num(x2, y2 + 1))] = 1;
	}
	if (q.empty())
	{
		puts("-1");
		return 0;
	}
	printf ("%lld\n", q.top().val);
	return 0;
}
相關文章
相關標籤/搜索