【2021夏纪中游记】2021.8.12模拟赛
作者:互联网
比赛概括:
\(\mathrm{sum}=100+50+80\)
我的 AK 啊呜呜呜呜。
T1 【NOIP2016提高A组模拟9.2】积木:
题目大意:
每秒中有一定的概率浮现幻象,持续 \(x\) 秒的幻象将产生 \(x^2\) 的幻象值。在 \(N\) 秒内期望产生的幻象值是多少。
思路:
麻了,原题。
T2 【NOIP2016提高A组模拟9.4】树上摩托:
题目大意:
把树去掉任意条边,拆成若干棵新树,求让每棵新树的节点数相同的方案数。
思路:
两个性质:
- 只要新树大小能整除于以当前结点为根的树的大小能够,他就可以拆。
- 对于每一种新树大小,它只能有一个方案。
代码:
纪中机子日常爆栈。
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 维护。
这个找第 \(k\) 大(小)的想法很像【Luogu P2048】[NOI2010] 超级钢琴和【Luogu P5283】[十二省联考2019]异或粽子。
代码:
#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;
}
标签:12,夏纪,Read,2021.8,ll,while,新树,&&,getchar 来源: https://www.cnblogs.com/GJY-JURUO/p/15132939.html