首页 > 其他分享 >题解:P8973 『GROI-R1』 继续深潜,为了同一个梦想

题解:P8973 『GROI-R1』 继续深潜,为了同一个梦想

时间:2024-10-04 21:49:07浏览次数:8  
标签:GROI putchar R1 int 题解 read maxN choose mod

换根 dp 模板题。

\(f_i\) 是在以 \(i\) 为根的子树中,以 \(i\) 为链的一个端点且 \(i\) 在点集中的合法点集个数。
\(ans_i\) 表示包含 \(i\) 的合法点集个数。

当 \(x\) 为树根时:

\[ans_x = {f_x \choose 2} - \sum_{s\in son}{2f_s+1 \choose 2} + f_x \]

简单解释一下,\({f_x \choose 2}\) 是在所有符合条件的链中随便选两条拼起来的数量,但是有可能会选到同一个子树中的两条链,这样拼起来的集合就不合法了,就像样例解释中的 \(\{1,3,4\}\) 一样,所以要减去。最后加上以 \(x\) 为链的一端的数量,也就是不需要拼的。

\(f_i\) 很好维护:

\[f_x= \sum_{s \in son}2f_s+1 \]

\(f_s\) 要乘 \(2\) 是因为 \(s\) 这个点可以选可以不选。即有可能是 \(\{\dots, s, x\}\),也有可能是 \(\{\dots, x\}\)。
加一是因为要加上集合为 \(\{s, x\}\) 的情况。

换根的时候根据上面的公式改下 \(f\) 数组就可以了。\(\sum{2f_s+1 \choose 2}\) 的部分用数组预处理出来就好了。

具体实现看代码。

#include <bits/stdc++.h>

using namespace std;

#define int long long

int read() {
	int s = 0, w = 1;
	char c = getchar();
	while (!isdigit(c)) {
		if (c == '-')
			w = -w;
		c = getchar();
	}
	while (isdigit(c)) {
		s = s * 10 + c - 48;
		c = getchar();
	}
	return s * w;
}
void pr(int x) {
	if (x < 0)
		putchar('-'), x = -x;
	if (x > 9)
		pr(x / 10);
	putchar(x % 10 + 48);
}
#define end_ putchar('\n')
#define spc_ putchar(' ')

const int maxN = 5e5 + 7, mod = 1e9 + 7;

const int m2 = 500000004;
// 2 的逆元

int n;

vector<int> E[maxN];

int f[maxN], s[maxN], A[maxN], ans;
// s 数组是预处理公式中求和的部分, A[i] 为 ans[i]

int C(int x) {
	return x * (x - 1 + mod) % mod * m2 % mod;
}

void dfs(int x, int fa) {
	for (int to : E[x])
		if (to != fa) {
			dfs(to, x);
			f[x] += f[to] * 2 + 1;
			f[x] %= mod;
			s[x] += C(f[to] * 2 + 1);
			s[x] %= mod;
		}
}

int ff[maxN];

void calc(int x, int fa) {
	A[x] = ((C(f[x]) - s[x] + mod) % mod + f[x]) % mod;

	for (int to : E[x]) {
		if (to == fa)
			continue;
		int fx = f[x], fto = f[to];
		int S = s[to];
		f[x] -= f[to] * 2 + 1;
		f[x] = (f[x] + mod * 2) % mod;
        // 这里要注意乘 2,因为上面的 f[to] 乘 2 了,只加一个 mod 有可能不够。

		f[to] += f[x] * 2 + 1;
		f[to] %= mod;

		s[to] += C(f[x] * 2 + 1);
		s[to] %= mod;

		calc(to, x);

		f[x] = fx, f[to] = fto;
		s[to] = S;
	}
}

signed main() {
	n = read();
	for (int i = 1; i < n; i++) {
		int u = read(), v = read();
		E[u].emplace_back(v);
		E[v].emplace_back(u);
	}
	dfs(1, 0);
	calc(1, 0);
	
	for (int i = 1; i <= n; i++)
		ans ^= A[i] * i;
	pr(ans), end_;
}

标签:GROI,putchar,R1,int,题解,read,maxN,choose,mod
From: https://www.cnblogs.com/ccxswl/p/18447376

相关文章

  • [题解][洛谷P3584] LAS
    题目描述有n个蛋糕和n个人,每个蛋糕的热量是Ci。第i个人可以选择吃第i或第i+1个蛋糕,第n个人可以选择吃第n或第1个蛋糕。若一个蛋糕被两个人吃,那么每个人得到的热量是Ci/2.若一个人改变自己的选择,得到的热量增加,那么他会不满意。试输出让所有人满意的解,输出每个人吃蛋糕的序号......
  • Centos7 停止维护之后 升级gcc||找不到devtoolset-8-gcc* 问题解决方案
    为了去小米澎湃互联组,感觉必须得拿下linux网络编程,今天第一步这个centos就给我拉了坨大的问题实质SCL源没换,相信你也在别的教程上看到要安装centos-release-scl吧?有坑!安装完成后在/etc/yum.repos.d目录下会出现CentOS-SCLo-scl.repo和CentOS-SCLo-scl-rh.repo两个文件,......
  • [题解][洛谷P1578] 奶牛浴场
    题目描述在长宽为L,W的二维平面上有n个障碍点,试找到一个不覆盖任何障碍点(但点可以在边缘线上的)面积最大的矩形(长宽均与坐标轴平行)。输出面积。题意分析n的范围在5e3,考虑O(n2)的做法。易得面积最大的矩形四条边要么有障碍点,要么覆盖的边界。否则四条边可以继续扩展,面积会变得更......
  • [题解][洛谷P1633] 二进制
    题目描述有三个整数A,B,C,构造三个整数X,Y,Z满足:1.A,B,C在二进制下1的数量分别与X,Y,Z相等;2.X,Y,Z在二进制下的长度不超过A,B,C的最大长度;3.X+Y=Z。输出Z的最小值,若不存在Z,输出-1。题意分析首先考虑X,Y在什么情况下会使1的数量发生改变。设x,y,z分别表示X,Y,Z中1的数量,则......
  • CF542C题解
    传送门:https://codeforces.com/problemset/problem/542/C我们把序列的映射关系看作\(i\rightarrowf(i)\)的边,要使\(f(f(i))=f(i)\),显然存在\(i\)点距离不超过\(1\)的长度为\(1\)的自环。推广到\(f^{(k)}(x)\)满足题意则会在距离\(x\)点距离不超过\(k\)的长度为\(k\)的环。我们......
  • CF242D题解
    传送门:https://codeforces.com/problemset/problem/242/D对于一个点,显然一旦达到额定值后,其他任何操作都无法使他减小,于是我们得出一个贪心性质,当且仅当一个点不合法时,才取增加他的值。同理,我们可以证明,问题必定有解,因为若一个点被选择,必定是因为其曾不合法,选择后使其\(+1\)合法,......
  • CF549B题解
    传送门:https://codeforces.com/problemset/problem/549/B和CF242C思路完全相同,对于一个点,显然一旦达到额定值后,其他任何操作都无法使他减小,于是我们得出一个贪心性质,当且仅当一个点不合法时,才取增加他的值。同理,我们可以证明,问题必定有解,因为若一个点被选择,必定是因为其曾不合法,......
  • [题解]P7077 [CSP-S2020] 函数调用
    P7077[CSP-S2020]函数调用题意简述给定一个长度为\(n\)的序列\(a_1,a_2,\dots,a_n\),给定\(m\)个函数,每个函数可能是下面\(3\)种类型,用\(T_x\)表示函数\(x\)的类型:\(T_x=1\),对下标\(p\)增加\(v\)。\(T_x=2\),对所有元素乘\(v\)。\(T_x=3\),由若干类型\(1\)和类型\(2\)组成......
  • 【题解】B - 三元上升子序列
    目录题目内容DescriptionInputOutput数据规模与约定思路代码题目内容DescriptionErwin最近对一种叫thair的东西巨感兴趣。。。在含有\(n\)个整数的序列\(a_1,a_2,\ldots,a_n\)中,三个数被称作thair当且仅当\(i\ltj\ltk\)且\(a_i\lta_j\lta_k\)。求一个序列中thair......
  • BUUCTF_MISC题解析(3,4)
    3.你竟然赶我走搜索010editor官网,点第一个页面,下载010editor(十六进制编译器)(黄色图标),直接010editor打开(或者使用stegSolve)一般情况用ctrl+f进入字符串搜索查看是否有插入的flag信息,就可以在文件尾看到flag是flag{stego_is_s0_bor1ing} 4.二维码扫码识别二维码,发现隐......