6.26-7.4做题记录

发布时间 2023-07-05 08:35:40作者: Svemit
  1. P3398

没去想最优解,无脑树剖。

  1. P5854

看到大纲里有就去学了下,不过没过几天现在好像忘了。

  1. P8865

组合数学能力还是很差,自己没推出式子来。

  1. P3608

离散化完拿树状数组乱搞。

  1. P9124

挺妙的感觉,考场上的时候没做出来。

  1. P9186

挺一眼的,不过细节有点难调。

  1. P7527

一开始当二维数点去做,没调出来换了种做法。

  1. B3609

复习强连通分量。

  1. P2341

显然对于一个环所有点都能到,缩点后如果出度为 \(0\) 的只有一个就是答案。

  1. P2272

缩点完拓扑排序+最长路计数。

  1. P2403

建图挺妙的,想不到。

  1. P1262

挺板的,答案也比较好观察出来。

  1. P4306

了解了下bitset。

  1. P3089

写的暴力dp

\(dp[i][j] = max(dp[j][k]) + w[i]\)

  1. abc147f

\(lst_i\)\(a_i\) 上一次出现的位置,查询区间 \([l, r]\) 变为查询满足 \(l \leq i \leq r , 1 \leq lst_i \leq l - 1\) 的个数。

  1. P3572

每个 \(k\) 跑一遍单调队列。

  1. P2216

先跑行的单调队列存入新数组,新数组再跑一边。

  1. P2845

每个点搜完后看看有没有自己能开灯的点可以拓展。

  1. P8773

也是记录 \(lst_i\),对于区间 \([l, r]\) 必须满足有 \(l \leq lst_i\)。线段树和st表都行。

  1. P9435

换根dp。
不妨钦定 \(1\) 为根
\(dp1_u\) 表示以 \(u\) 为根的子树所有节点到 \(u\) 的贡献。
\(dp2_u\) 表示 \(u\) 的子树外的点到 \(u\) 的贡献。
子节点 \(v\)\(u\) 的贡献为
\(dp1[v] * mylog(w[u]) + siz[v] * w[u]\)

code
LL mylog(LL v)
{
	if(v == 0) return 10;
	int res = 0;
	while(v) res ++, v /= 10;
	return pow(10, res);
} 
LL val(int u, int v) // u -> v 的贡献
{
	return (dp1[u] * mylog(w[v]) + siz[u] * w[v]) % mod;
}
void dfs1(int u, int fa)
{
	siz[u] = 1;
	for(auto v : e[u])
		if(v != fa)
		{
			dfs1(v, u);
			siz[u] += siz[v];
			dp1[u] = (dp1[u] + dp1[v]) % mod;
		}
	dp1[u] = (dp1[u] * mylog(w[u]) % mod + w[u] * siz[u] % mod) % mod;
}
void dfs2(int u, int fa)
{
	for(auto v : e[u])
		if(v != fa)
		{
			dp2[v] = ((dp1[u] + dp2[u] - val(v, u) - w[u]) % mod * mylog(w[v]) % mod + (siz[1] - siz[v] + 1) % mod * w[v] % mod) % mod;
			dfs2(v, u);
		}
}
  1. P2986
code
void dfs1(int u, int fa)
{
	// dp1[u] = dp1[v] + siz[v] * val[i];
	siz[u] = c[u];
	for(int i = h[u]; i; i = nxt[i])
	{
		int v = to[i];
		if(v == fa) continue;
		dfs1(v, u);
		siz[u] += siz[v];
		dp1[u] += dp1[v] + siz[v] * val[i];
	}
}
void dfs2(int u, int fa)
{
	// 1->u dp2[u]=dp1[1]-siz[u]*val[i]+(siz[1]-siz[u])*val[i]
	// u->v dp2[v](dp1[u]+dp2[u]-dp1[v]-siz[v]*val[i])+(siz[1]-siz[v])*val[i]
	for(int i = h[u]; i; i = nxt[i])
	{
		int v = to[i];
		if(v == fa) continue;
		dp2[v] = (dp1[u] + dp2[u] - dp1[v] - siz[v] * val[i]) + (siz[1] - siz[v]) * val[i]; 
		dfs2(v, u);
	}
}