#include<bits/stdc++.h> usingnamespacestd; typedefunsignedlonglong ull; const ull base = 13331; constint N = 5e5 + 5; int n, len, res; char s[N]; ull r, l[N], b[N]; intmain(){ scanf("%d%s", &n, s + 1); b[0] = 1; for (int i = 1; i <= n; i++) b[i] = b[i - 1] * base; for (int i = 1; i <= n; i++) l[i] = l[i - 1] * base + s[i]; for (int i = n; i >= 1; i--) { r = r * base + s[i]; len++; if (i >= len) { ull now1 = l[i] - l[i - len] * b[len]; if (now1 == r) res = max(res, len * 2 - 1); } if (i >= len + 1) { ull now2 = l[i - 1] - l[i - 1 - len] * b[len]; if (now2 == r) res = max(res, len * 2); } } printf("%d\n", n - res); return0; }
C. Bob in Wonderland
题意
把一棵树变为一条链的最少操作次数$(n \in [1, 3e5])$。
Solution
其实就是不断把度大于2的点转移到头或者尾,因此答案就是所有度数大于2的点减去2的和。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#include<bits/stdc++.h> usingnamespacestd; int n, x, y, res, d[500005]; intmain(){ scanf("%d", &n); for (int i = 1; i < n; i++) { scanf("%d%d", &x, &y); d[x]++; d[y]++; } for (int i = 1; i <= n; i++) res += max(d[i] - 2, 0); printf("%d\n", res); return0; }