T1
Description
Given a \ (n-\) points directed graph, each point may be black, white or colorless, no start edge this FIG. To complete this picture you supplement:
- Each point of the colorless or white painted black.
- For \ (\ FORALL. 1 \ Leq I <J \ n-Leq \) , you can choose to connect \ (i → j \) are connected to the edges or not.
Define a path is valid, if and only if different neighboring color points on the path, the path may go through only one point.
FIG define a legitimate, valid if and only if this number of paths is an odd FIG.
How many seek supplementary scheme makes drawing legitimate, the answer to \ (998 244 353 \) modulo.
\ (1 \ leq n \ leq 2 × 10 ^ 5 \) .
Solution
We remember \ (g_i \) represents the point \ (i \) as a legitimate path bar at the end of the number \ (\% 2 \) results. FIG To make legitimate, so that \ (n-\) points in \ (g_i = 1 \) is an odd number.
Obviously \ (G_i = (\ sum_ {J} =. 1. 1-I ^ {} [color_i ≠ color_j] G_J) \% 2 \ XOR \. 1 \) . Can be found in \ (g_i \) only with \ (i \) and even a few \ (color_i ≠ color_j \) and \ (g_j = 1 \) point related. Even assuming the \ (K \) such points \ (J \) . If \ (K \) is even, \ (. 1 G_i = \) , or \ (G_i = 0 \) .
Consider \ (DP \) , denoted \ (f [i] [j ] [a] [b] \) representing the forward \ (I \) points, \ (G \) of XOR and are \ (j (j ∈ [0,1]) \) , \ (. 1 G = \) of the point, there are \ (a \) a white, \ (B \) th number of the program is black.
From \ (f [i-1] [j] [a] [b] \) transfer over. We enumerate the point \ (i \) dyed white or black. When the point \ (I \) may be colored white (point \ (I \) when the original is white or colorless), enumeration \ (I \) even this \ (B \) th points \ (K \ ) th, the following transfer: \ [F [I] [J \ XOR \. 1] [A +. 1] [B] + = F [I-. 1] [J] [A] [B] × h_0 [B] \] \ [F [I] [J] [A] [B] + = F [. 1-I] [J] [A] [B] × H_1 [B] \]
Wherein \ (h_0 [b] \) represents the size of \ (B \) selecting a set of programs in several of the even number of elements, \ (H_1 [B] \) represents the size of \ (B \) collection selecting a few odd number of program elements.
Clearly \ [B = 0: h_0 [B] =. 1, H_1 [B] = 0 \] \ [B> 0: h_0 [B] = H_1 [B] = 2. 1-B ^ {} \]
Thus mind \ (f [i] [j ] [c] [d], c∈ [0,1], d∈ [0,1] \) represents the former \ (I \) points, \ (G \) and to the exclusive oR \ (J \) , whether \ (a> 0 \) , if (b> 0 \) \ number of programs.
Time complexity \ (O (n-) \) .
Code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
template <class t>
inline void read(t & res)
{
char ch; bool fl = 0; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? fl = 1 : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + (ch ^ 48);
fl ? res = ~res + 1 : 0;
}
const int e = 2e5 + 5, mod = 998244353;
int f[e][2][2][2], n, ans, col[e], p[e];
inline void add(int &x, int y)
{
(x += y) >= mod && (x -= mod);
}
inline int plu(int x, int y)
{
add(x, y);
return x;
}
inline int s(int x, int y)
{
x += y;
return min(x, 1);
}
inline int mul(int x, int y)
{
return (ll)x * y % mod;
}
int main()
{
read(n);
int i, j, a, b;
for (i = 1; i <= n; i++) read(col[i]);
p[0] = 1;
for (i = 1; i <= n; i++) p[i] = plu(p[i - 1], p[i - 1]);
f[0][0][0][0] = 1;
for (i = 1; i <= n; i++)
for (j = 0; j <= 1; j++)
for (a = 0; a <= 1; a++)
for (b = 0; b <= 1; b++)
if (f[i - 1][j][a][b])
{
int v = f[i - 1][j][a][b];
if (col[i] != 1)
{
if (b)
{
add(f[i][j ^ 1][s(a, 1)][b], mul(v, p[i - 2]));
add(f[i][j][a][b], mul(v, p[i - 2]));
}
else add(f[i][j ^ 1][s(a, 1)][b], mul(v, p[i - 1]));
}
if (col[i] != 0)
{
if (a)
{
add(f[i][j ^ 1][a][s(b, 1)], mul(v, p[i - 2]));
add(f[i][j][a][b], mul(v, p[i - 2]));
}
else add(f[i][j ^ 1][a][s(b, 1)], mul(v, p[i - 1]));
}
}
for (a = 0; a <= 1; a++)
for (b = 0; b <= 1; b++)
add(ans, f[n][1][a][b]);
cout << ans << endl;
fclose(stdin);
fclose(stdout);
return 0;
}
T2
Description
Given a \ (n-\) points, \ (m \) without edges to FIG, now you get to each edge orientation.
Legal definition of a directed graph, if and only if there exists a point \ (U \) , so \ (1 \) can come \ (U \) and \ (2 \) can come \ (U \) .
Seeking \ (2 ^ m \) species directional scheme, how many there view after orientation is legitimate.
The answer to \ (9 + 10 ^ 7 \) modulo, \ (n-\ Leq 15, m \ Leq \ {n-FRAC (. 1-n-)} {2} \) .
Solution
Consider complement conversion, that is not calculated the number of legal orientation programs.
\ (S \) of the subgraph comprising \ (S \) points, two points are \ (S \) sides of the.
Enumerations \ (S, T \) , to ensure \ (1∈S, 2∈T, S∩T = \ varnothing \) . Has been determined the assumed: \ (F [S] \) represents a (S \) \ sides are oriented in the induced subgraph, such that \ (1 \) can come \ (S \) scheme in all points number, \ (G [T] \) represents a (T \) \ sides are oriented in the induced subgraph, such that \ (2 \) can come \ (T \) number of all points in the program.
We forced \ (1 \) come to the stage \ (S \) point other than \ (2 \) come to the stage \ (T \) points outside. So to ensure the absence of cross \ (S, T \) side, does not belong to \ (S∪T \) point and \ (S, T \) direction even in the edge points have been determined. Set \ (\ complement (S∪T) \ ) FIG derived promoter is the number of edges \ (CNT \) , then \ [ans + = f [S ] × g [T] × 2 ^ {cnt} \]
Next, consider how beg \ (f [S] \) . \ (g [T] \) Similarly.
Complement conversion are also contemplated, Shilling \ (f [S] = 2 ^ { subgraph the number of edges} S \) . Next, the enumeration \ (S \) is a proper subset \ (T \) , forced \ (1 \) can only go \ (T \) points. Then \ (T \) and \ (S∩ \ complement T \) direction between the edge has been determined, set \ (S∩ \ complement T \) FIG derived promoter is the number of edges \ (CNT \) , then \ [f [S] - = f [T] × 2 ^ {cnt} \] time complexity \ (O (n-^. 3) \) .
#include <bits/stdc++.h>
using namespace std;
#define ll long long
template <class t>
inline void read(t & res)
{
char ch;
while (ch = getchar(), !isdigit(ch));
res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + (ch ^ 48);
}
const int e = (1 << 15) + 5, mod = 1e9 + 7;
int f[e], g[e], h[e], n, m, ans, p[e], id, tmp;
inline void add(int &x, int y)
{
(x += y) >= mod && (x -= mod);
}
inline void del(int &x, int y)
{
(x -= y) < 0 && (x += mod);
}
inline int mul(int x, int y)
{
return (ll)x * y % mod;
}
int main()
{
read(n); read(m); read(id); tmp = 1 << n;
int i, x, y, s, t;
p[0] = 1;
for (i = 1; i <= m; i++)
{
read(x); read(y);
p[i] = 2ll * p[i - 1] % mod;
for (s = 0; s < tmp; s++)
if ((s & (1 << x - 1)) && (s & (1 << y - 1))) h[s]++;
}
ans = p[m];
f[1] = 1;
for (s = 2; s < tmp; s++)
if (s & 1)
{
f[s] = p[h[s]];
for (t = (s - 1) & s; t; t = (t - 1) & s)
del(f[s], mul(f[t], p[h[s ^ t]]));
}
g[2] = 1;
for (s = 3; s < tmp; s++)
if (s & 2)
{
g[s] = p[h[s]];
for (t = (s - 1) & s; t; t = (t - 1) & s)
del(g[s], mul(g[t], p[h[s ^ t]]));
}
for (i = 0; i < tmp; i++)
for (t = i; t; t = (t - 1) & i)
if (t & 2)
{
s = (tmp - 1) ^ i;
if (s & 1 && (h[s | t] - h[s] - h[t] == 0))
del(ans, mul(mul(f[s], g[t]), p[h[(tmp - 1) ^ (s | t)]]));
}
cout << ans << endl;
fclose(stdin);
fclose(stdout);
return 0;
}
T3
Description
Given a length \ (n-\) string contains only lowercase letters \ (S \) , you need to find a maximum \ (K \) , such that there is:
\ [1 \ l_1 the \ the r_1 <L 2 \ the r_2 <L_3 \ the r_3 <\ dots <l_k \ the r_k \ n \]
(I.e. \ (K \) intervals \ ([l_1, r_1] [ l_2, r_2] \ dots [l_k, r_k] \) is incremented and the left and right endpoints mutually disjoint)
Such that for each \ (. 1 \ Le I <K \) , satisfies \ (s [l_ {i + 1} \ dots r_ {i + 1}] \) is \ (s [l_i \ dots r_i ] \) of a strict string.
Wherein \ (s [l \ dots r ] \) represents the string \ (S \) of \ (L \) to the second \ (R & lt \) a string of characters.
String \ (A \) is the string \ (B \) of a strict sequence, if and only if the \ (B \) beginning and end of each of a plurality of characters to delete (delete characters from the beginning and end of a the number may be zero, but the number of characters deleted and must be greater than \ (0 \) ) can be obtained \ (a \) .
\ (n \ leq 5 × 10 ^ 5 \) .
Solution
We must first know a few properties:
- Under optimum circumstances, all \ (s [l_i \ dots r_i ] \) is \ (s [l_ {i + 1} \ dots r_ {i + 1}] \) at the beginning or end of the character is added to give and \ (L_K = r_k \) .
- Note \ (F_i \) represents \ (l_1 = i \) when, \ (K \) is the largest number, there are \ (f_i \ leq f_ {i + 1} +1 \)
Consider proof properties \ (2 \) , i.e. \ (F_. 1} + {I \ F_i-GEQ. 1 \) .
Has been assumed that a \ (L_1 = I \) , and \ (f_i = k \) of the partitioning scheme. In this embodiment, when the \ (s [l_j \ dots r_j ] \) is \ (s [l_ {j + 1} \ dots r_ {j + 1}] \) at the beginning of adding the resulting character, denoted \ (a_j = 0 \) , or \ (a_j = 1 \) . Consider remove \ (s [l_1 \ dots r_1 ] \) of the first character, i.e. \ (L_1 ++ \) .
Next Order \ (. 1 J = \) , if the \ (= a_j. 1 \) , then let \ (menthoxypropane. 1 {+} J ++, J ++ \) , the cycle continues. Otherwise, this time must be \ (S [l_j \ DOTS r_j] = S [menthoxypropane +. 1 {J} \ DOTS + R_ {J}. 1] \) , then the \ (s [l_ {j + 1} \ dots r_ {j + 1}] \) can be deleted. This resulted in a \ (f_ {i + 1} = k \) of the partitioning scheme.
Thus each Shilling \ (F_i = F_ {I} + 1'd. 1 + \) , determines the \ (F_i \) whether to take, can not just \ (F_i - \) , until \ (F_i =. 1 \) . The answer is \ (max (F_i) \) .
Determining whether the problem is converted to \ (F_i \ Leq MID \) . There is a clear need for a \ (j \) satisfies the following \ (3 \) conditions:
- \(i+mid\leq j\leq n\)
- \(max(lcp(suf_i,suf_j),lcp(suf_{i+1},suf_j)\geq mid-1\)
- \(f_j\geq mid-1\)
Obtaining \ (sa, rank \) array, conditions \ (2 \) can be viewed as \ (rank_j∈ [L, R & lt] \) , \ ([L, R & lt] \) can be bipartite + \ (\ text {RMQ} \) is obtained.
That is to satisfy our requirements \ (i + mid \ leq j \ leq n, rank_j∈ [l, r] \) a \ (max (F_j) \) . Chairman of the tree can be, the time complexity \ (O (the n-\ the n-log) \) .
Code
#include <bits/stdc++.h>
using namespace std;
const int e = 1e6 + 5;
struct node
{
int l, r, w;
}c[e * 30];
char s[e];
int rk[e], h[e], w[e], sa[e], a[e], b[e], tot, tmp[e], f[e], n, ans = 1, d[e][20], rt[e];
int logn[e], pool;
inline void init()
{
int i, k, r = 0, j;
for (i = 1; i <= n; i++) w[s[i]]++;
for (i = 1; i <= 256; i++) w[i] += w[i - 1];
for (i = n; i >= 1; i--) sa[w[s[i]]--] = i;
for (i = 1; i <= n; i++)
if (s[sa[i - 1]] == s[sa[i]]) a[sa[i]] = r;
else a[sa[i]] = ++r;
for (k = 1; r < n; k <<= 1)
{
tot = 0;
for (i = n - k + 1; i <= n; i++) b[++tot] = i;
for (i = 1; i <= n; i++)
if (sa[i] > k) b[++tot] = sa[i] - k;
for (i = 1; i <= n; i++) w[a[b[i]]] = 0;
for (i = 1; i <= n; i++) w[a[b[i]]]++;
for (i = 2; i <= n; i++) w[i] += w[i - 1];
for (i = n; i >= 1; i--) sa[w[a[b[i]]]--] = b[i];
for (i = 1; i <= n; i++) tmp[i] = a[i];
r = 0;
for (i = 1; i <= n; i++)
if (tmp[sa[i]] == tmp[sa[i - 1]] && tmp[sa[i] + k] == tmp[sa[i - 1] + k])
a[sa[i]] = r; else a[sa[i]] = ++r;
}
for (i = 1; i <= n; i++) rk[sa[i]] = i;
for (i = 1; i <= n; i++)
{
if (rk[i] == 1) continue;
h[i] = max(0, h[i - 1] - 1);
int x = sa[rk[i] - 1];
while (s[i + h[i]] == s[x + h[i]] && max(i, x) + h[i] <= n) h[i]++;
}
logn[0] = -1;
for (i = 1; i <= n; i++) logn[i] = logn[i >> 1] + 1, d[i][0] = h[sa[i]];
for (j = 1; (1 << j) <= n; j++)
for (i = 1; i + (1 << j) - 1 <= n; i++)
d[i][j] = min(d[i][j - 1], d[i + (1 << j - 1)][j - 1]);
}
inline int ask(int l, int r)
{
if (l > r) swap(l, r);
if (l == r) return n - sa[l] + 1;
l++;
int k = logn[r - l + 1];
return min(d[l][k], d[r - (1 << k) + 1][k]);
}
inline void insert(int y, int &x, int l, int r, int s, int v)
{
c[x = ++pool] = c[y];
c[x].w = max(c[x].w, v);
if (l == r) return;
int mid = l + r >> 1;
if (s <= mid) insert(c[y].l, c[x].l, l, mid, s, v);
else insert(c[y].r, c[x].r, mid + 1, r, s, v);
}
inline int query(int x, int l, int r, int s, int t)
{
if (l == s && r == t) return c[x].w;
int mid = l + r >> 1;
if (t <= mid) return query(c[x].l, l, mid, s, t);
else if (s > mid) return query(c[x].r, mid + 1, r, s, t);
else return max(query(c[x].l, l, mid, s, mid),
query(c[x].r, mid + 1, r, mid + 1, t));
}
inline void upt(int &s, int &t, int x, int len)
{
int l = 1, pos = rk[x], r = pos;
s = pos;
while (l <= r)
{
int mid = l + r >> 1;
if (ask(mid, pos) >= len) s = mid, r = mid - 1;
else l = mid + 1;
}
t = pos;
l = pos; r = n;
while (l <= r)
{
int mid = l + r >> 1;
if (ask(pos, mid) >= len) t = mid, l = mid + 1;
else r = mid - 1;
}
}
inline bool check(int x, int mid)
{
int l, r, s = x + mid, t = n;
if (s > t) return 0;
upt(l, r, x, mid - 1);
if (query(rt[s], 1, n, l, r) >= mid - 1) return 1;
upt(l, r, x + 1, mid - 1);
return query(rt[s], 1, n, l, r) >= mid - 1;
}
int main()
{
cin >> n;
scanf("%s", s + 1);
n = strlen(s + 1);
init();
f[n] = 1;
int i;
insert(rt[n + 1], rt[n], 1, n, rk[n], 1);
for (i = n - 1; i >= 1; i--)
{
f[i] = f[i + 1] + 1;
while (f[i] > 1 && !check(i, f[i])) f[i]--;
ans = max(ans, f[i]);
insert(rt[i + 1], rt[i], 1, n, rk[i], f[i]);
}
cout << ans << endl;
fclose(stdin);
fclose(stdout);
return 0;
}