(A,B,C) ( A , B , C ) 经过一次变换之后变成 (B+C,A+C,A+B) ( B + C , A + C , A + B ) 再变换变成 (A+B+C+A,A+B+C+B,A+B+C+C) ( A + B + C + A , A + B + C + B , A + B + C + C ) 。
如果 k k 是偶数答案为 A−B A − B 否则是 B−A B − A 。
#include
using namespace std;
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;
template <typename T> inline void Read(T &x) {
char c = getchar();
bool f = false;
for (x = 0; !isdigit(c); c = getchar()) {
if (c == '-') {
f = true;
}
}
for (; isdigit(c); c = getchar()) {
x = x * 10 + c - '0';
}
if (f) {
x = -x;
}
}
template <typename T> inline bool CheckMax(T &a, const T &b) {
return a < b ? a = b, true : false;
}
template <typename T> inline bool CheckMin(T &a, const T &b) {
return a > b ? a = b, true : false;
}
int main() {
#ifdef wxh010910
freopen("d.in", "r", stdin);
#endif
int a, b, c;
LL k;
Read(a), Read(b), Read(c), Read(k);
if (k & 1) {
printf("%d\n", b - a);
} else {
printf("%d\n", a - b);
}
#ifdef wxh010910
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
return 0;
}
将问题倒着做,变成可以将两端的插入到中间,那么贪心保留一个最长上升子串即可。
#include
using namespace std;
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;
template <typename T> inline void Read(T &x) {
char c = getchar();
bool f = false;
for (x = 0; !isdigit(c); c = getchar()) {
if (c == '-') {
f = true;
}
}
for (; isdigit(c); c = getchar()) {
x = x * 10 + c - '0';
}
if (f) {
x = -x;
}
}
template <typename T> inline bool CheckMax(T &a, const T &b) {
return a < b ? a = b, true : false;
}
template <typename T> inline bool CheckMin(T &a, const T &b) {
return a > b ? a = b, true : false;
}
const int N = 200005;
int n, ans, a[N];
int main() {
#ifdef wxh010910
freopen("d.in", "r", stdin);
#endif
Read(n), ans = 1;
for (int i = 1, x; i <= n; ++i) {
Read(x), a[x] = i;
}
for (int i = 1, c = 0; i <= n; ++i) {
if (a[i] > a[i - 1]) {
CheckMax(ans, ++c);
} else {
c = 1;
}
}
printf("%d\n", n - ans);
#ifdef wxh010910
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
return 0;
}
贪心加就行了。
#include
using namespace std;
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;
template <typename T> inline void Read(T &x) {
char c = getchar();
bool f = false;
for (x = 0; !isdigit(c); c = getchar()) {
if (c == '-') {
f = true;
}
}
for (; isdigit(c); c = getchar()) {
x = x * 10 + c - '0';
}
if (f) {
x = -x;
}
}
template <typename T> inline bool CheckMax(T &a, const T &b) {
return a < b ? a = b, true : false;
}
template <typename T> inline bool CheckMin(T &a, const T &b) {
return a > b ? a = b, true : false;
}
const int N = 200005;
int n, a[N];
LL ans;
int main() {
#ifdef wxh010910
freopen("d.in", "r", stdin);
#endif
Read(n);
for (int i = 1; i <= n; ++i) {
Read(a[i]);
}
if (a[1]) {
puts("-1");
return 0;
}
for (int i = 1; i < n; ++i) {
if (a[i + 1] - a[i] > 1) {
puts("-1");
return 0;
}
}
for (int i = 1; i <= n; ++i) {
if (a[i]) {
++ans;
if (a[i] != a[i - 1] + 1) {
ans += a[i] - 1;
}
}
}
printf("%lld\n", ans);
#ifdef wxh010910
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
return 0;
}
假设直径是 D D ,那么答案为 ⌊D2⌋ ⌊ D 2 ⌋ 。然后以直径的一个或者两个中点为根,将其他东西填满即可。注意如果直径长度为偶数,可以让直径长度加 1 1 来减小第二问的答案。
#include
using namespace std;
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;
template <typename T> inline void Read(T &x) {
char c = getchar();
bool f = false;
for (x = 0; !isdigit(c); c = getchar()) {
if (c == '-') {
f = true;
}
}
for (; isdigit(c); c = getchar()) {
x = x * 10 + c - '0';
}
if (f) {
x = -x;
}
}
template <typename T> inline bool CheckMax(T &a, const T &b) {
return a < b ? a = b, true : false;
}
template <typename T> inline bool CheckMin(T &a, const T &b) {
return a > b ? a = b, true : false;
}
const int N = 105;
vector <int> adj[N], seq[N];
int n, dep[N], par[N];
LL ans, f[N], g[N];
inline void DFS(int x, int p) {
par[x] = p, dep[x] = dep[p] + 1;
for (auto y : adj[x]) {
if (y != p) {
DFS(y, x);
}
}
}
inline LL Solve(int x) {
DFS(x, 0);
int maxdep = 0;
for (int i = 1; i <= n; ++i) {
CheckMax(maxdep, dep[i]);
}
for (int i = 1; i <= maxdep; ++i) {
seq[i].clear();
}
for (int i = 1; i <= n; ++i) {
seq[dep[i]].pb(i);
}
LL ret = 1;
for (int i = maxdep - 1; i; --i) {
int maxson = 0;
for (auto x : seq[i]) {
int cnt = 0;
for (auto y : adj[x]) {
if (dep[y] == i + 1) {
++cnt;
}
}
CheckMax(maxson, cnt);
}
ret *= maxson;
}
return ret;
}
inline LL Solve(int x, int y) {
dep[y] = 0, DFS(x, y), dep[x] = 0, DFS(y, x), dep[x] = 1;
int maxdep = 0;
for (int i = 1; i <= n; ++i) {
CheckMax(maxdep, dep[i]);
}
for (int i = 1; i <= maxdep; ++i) {
seq[i].clear();
}
for (int i = 1; i <= n; ++i) {
seq[dep[i]].pb(i);
}
LL ret = 1;
for (int i = maxdep - 1; i; --i) {
int maxson = 0;
for (auto x : seq[i]) {
int cnt = 0;
for (auto y : adj[x]) {
if (dep[y] == i + 1) {
++cnt;
}
}
CheckMax(maxson, cnt);
}
ret *= maxson;
}
return ret << 1;
}
int main() {
#ifdef wxh010910
freopen("d.in", "r", stdin);
#endif
Read(n);
for (int i = 1, x, y; i < n; ++i) {
Read(x), Read(y);
adj[x].pb(y), adj[y].pb(x);
}
DFS(1, 0);
int s = 0;
for (int i = 1; i <= n; ++i) {
if (dep[i] > dep[s]) {
s = i;
}
}
DFS(s, 0);
int t = 0;
for (int i = 1; i <= n; ++i) {
if (dep[i] > dep[t]) {
t = i;
}
}
if (!(dep[s] + dep[t] & 1)) {
int mid = dep[s] + dep[t] >> 1, r;
for (r = t; dep[r] != mid; r = par[r]);
ans = Solve(r);
for (auto x : adj[r]) {
CheckMin(ans, Solve(r, x));
}
printf("%d %lld\n", mid, ans);
} else {
int mid1 = dep[s] + dep[t] >> 1, mid2 = dep[s] + dep[t] + 1 >> 1, r1, r2;
for (r1 = t; dep[r1] != mid1; r1 = par[r1]);
for (r2 = t; dep[r2] != mid2; r2 = par[r2]);
printf("%d %lld\n", mid1, Solve(r1, r2));
}
#ifdef wxh010910
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
return 0;
}
不难发现如果新增的位置与原来这个位置的值相等,那么可以认为填的后面一个位置的值而不是这个位置。将每个填的数向它后面的数连边,那么构成了一棵树,做一个树形DP就行了。
#include
using namespace std;
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;
template <typename T> inline void Read(T &x) {
char c = getchar();
bool f = false;
for (x = 0; !isdigit(c); c = getchar()) {
if (c == '-') {
f = true;
}
}
for (; isdigit(c); c = getchar()) {
x = x * 10 + c - '0';
}
if (f) {
x = -x;
}
}
template <typename T> inline bool CheckMax(T &a, const T &b) {
return a < b ? a = b, true : false;
}
template <typename T> inline bool CheckMin(T &a, const T &b) {
return a > b ? a = b, true : false;
}
const int N = 305;
int n, m, mod, c[N][N], f[N][N], g[N][N];
int main() {
#ifdef wxh010910
freopen("d.in", "r", stdin);
#endif
Read(n), Read(m), Read(mod);
for (int i = 0; i <= n; ++i) {
c[i][0] = 1;
for (int j = 1; j <= i; ++j) {
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
}
}
for (int i = 1; i <= m; ++i) {
f[1][i] = g[1][i] = (m - i + 1) % mod;
}
for (int i = 2; i <= n; ++i) {
for (int j = m - 1; j; --j) {
f[i][j] = (g[i - 1][j + 1] + f[i][j + 1]) % mod;
}
for (int j = 1; j <= m; ++j) {
g[i][j] = f[i][j];
for (int k = 1; k < i; ++k) {
g[i][j] = (1LL * f[k][j] * g[i - k][j] % mod * c[i - 1][k - 1] + g[i][j]) % mod;
}
}
}
printf("%d\n", g[n][1]);
#ifdef wxh010910
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
return 0;
}
考虑如何表示一个串的所有子序列,建一个类似子序列自动机的东西,比如 000110101 000110101 可以转移到 0[00110101] 0 [ 00110101 ] 或者 1[10101] 1 [ 10101 ] ,其中 s[t] s [ t ] 表示选了 s s ,要在 t t 中选一个子序列。建出一个DAG之后跑DP即可。
#include
using namespace std;
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;
template <typename T> inline void Read(T &x) {
char c = getchar();
bool f = false;
for (x = 0; !isdigit(c); c = getchar()) {
if (c == '-') {
f = true;
}
}
for (; isdigit(c); c = getchar()) {
x = x * 10 + c - '0';
}
if (f) {
x = -x;
}
}
template <typename T> inline bool CheckMax(T &a, const T &b) {
return a < b ? a = b, true : false;
}
template <typename T> inline bool CheckMin(T &a, const T &b) {
return a > b ? a = b, true : false;
}
const int N = 1048580;
const int M = 25;
int n, m, len, ans, f[M][N], g[M][N];
char s[N];
int main() {
#ifdef wxh010910
freopen("d.in", "r", stdin);
#endif
Read(n), Read(m);
for (int i = 0; i <= n; ++i) {
scanf("%s", s);
for (int j = 0; j < 1 << i; ++j) {
if (s[j] == '1') {
f[i][j] = 1;
}
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < 1 << i; ++j) {
int b = j >> (i - 1) & 1, r = 0;
for (; r < i && (j >> i - r - 1 & 1) == b; ++r);
g[i][j] = r == i ? -1 : r;
}
}
for (int i = 0; i <= n; ++i) {
for (int j = 1; i + j <= n; ++j) {
for (int k = 0; k < 1 << i + j; ++k) {
f[i][k >> j] += f[i + j][k];
int t = g[j][k & (1 << j) - 1];
if (~t) {
f[i + j - t][(k >> j << j - t) | (k & (1 << j - t) - 1)] += f[i + j][k];
}
}
}
for (int j = (1 << i) - 1; ~j; --j) {
if (f[i][j] >= m) {
len = i, ans = j;
}
}
}
for (int i = len - 1; ~i; --i) {
putchar((ans >> i & 1) + '0');
}
putchar(10);
#ifdef wxh010910
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
return 0;
}