n为字符串长度,len为s长度
想到正难则反,先求出合法的字符串数量,再用总数 2 6 n 26^n 26n去减就好了
类似于隔板法的思想,s字符串总共有 l e n + 1 len+1 len+1个空位可以放字符串,长度为剩下的 n − l e n n-len n−len
考虑在s前面加入 n − l e n n-len n−len个字符,总共有 2 6 n − l e n 26^{n-len} 26n−len种
如果插入在s第一个字符后面(往后移一格)还是 2 6 n − l e n 26^{n-len} 26n−len种吗?
显然不是,因为前面已经有一个字符了,有一个26应该为25
往后 l e n len len个空位都是这样,所以答案是:
2 6 n − ( 2 6 n − l e n + l e n ∗ 25 ∗ 2 6 n − l e n − 1 ) 26^n-(26^{n-len}+len*25*26^{n-len-1}) 26n−(26n−len+len∗25∗26n−len−1)
注意特判 n = l e n n=len n=len的情况
Code:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cmath>
#include <algorithm>
#define qy 998244353
#define MAXN 10000010
#define int long long
using namespace std;
char s[MAXN];
int n, len;
inline int POW (int a, int b) {
if (! b) return 1; if (b == 1) return a;
int base = 1;
while (b) {
if (b & 1) base = base * a % qy;
a = a * a % qy, b >>= 1;
}
return base;
}
signed main () {
freopen ("magic.in", "r", stdin); freopen ("magic.out", "w", stdout);
scanf ("%lld", &n), scanf ("%s", s + 1), len = strlen (s + 1);
int k1 = POW (26, n), k2 = POW (26, n - len), k3 = len * 25 * POW (26, n - len - 1) % qy;
return printf ("%lld\n", ((((k1 - k2) % qy + qy) % qy - k3) % qy + qy) % qy), 0;
}
这道题就是星际导航重题哈哈哈
刚刚做完,模拟赛给我来这道
一眼kruskal重构树切掉了
Code:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 400000
using namespace std;
struct fls {int to, next;} edge[MAXN << 2];
struct Node {int x, y, z;} data[MAXN];
int depth[MAXN], top[MAXN], head[MAXN << 2], father[MAXN], son[MAXN];
int size[MAXN], f[MAXN], val[MAXN], n, m, q, cnt;
inline int read () {
register int s = 0, w = 1;
register char ch = getchar ();
while (! isdigit (ch)) {if (ch == '-') w = -1; ch = getchar ();}
while (isdigit (ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar ();}
return s * w;
}
inline bool cmp (Node a, Node b) {return a.z < b.z;}
inline void connect (int u, int v) {edge[++cnt].to = v, edge[cnt].next = head[u], head[u] = cnt;}
int getfather (int x) {return x == f[x] ? x : f[x] = getfather (f[x]);}
inline int LCA (int x, int y) {
while (top[x] != top[y]) {
if (depth[top[x]] < depth[top[y]]) swap (x, y);
x = father[top[x]];
}
return depth[x] > depth[y] ? y : x;
}
void DFS1 (int now, int fa, int d) {
father[now] = fa, depth[now] = d, size[now] = 1; int maxson = -1;
for (register int i = head[now]; i; i = edge[i].next) {
int v = edge[i].to; if (v == fa) continue;
DFS1 (v, now, d + 1), size[now] += size[v];
if (size[v] > maxson) maxson = size[v], son[now] = v;
}
}
void DFS2 (int now, int top_heavy) {
top[now] = top_heavy; if (! son[now]) return;
DFS2 (son[now], top_heavy);
for (register int i = head[now]; i; i = edge[i].next) {
int v = edge[i].to;
if (v != son[now] && v != father[now]) DFS2 (v, v);
}
}
int main () {
freopen ("graph.in", "r", stdin); freopen ("graph.out", "w", stdout);
n = read (), m = read (), q = read ();
for (register int i = 1; i <= m; i++)
data[i].x = read (), data[i].y = read (), data[i].z = read ();
sort (data + 1, data + m + 1, cmp); int now = n;
for (register int i = 1; i <= n * 2; i++) f[i] = i;
for (register int i = 1; i <= m; i++) {
int x = data[i].x, y = data[i].y;
int xx = getfather (x), yy = getfather (y);
if (xx != yy) {
f[xx] = f[yy] = ++now;
connect (xx, now), connect (now, xx);
connect (yy, now), connect (now, yy);
val[now] = data[i].z;
}
}
for (register int i = now; i; i--)
if (! depth[i]) DFS1 (i, 0, 1), DFS2 (i, i);
for (register int i = 1; i <= q; i++) {
int x = read (), y = read ();
if (getfather (x) != getfather (y)) puts ("-1");
else printf ("%d\n", val[LCA (x, y)]);
}
return 0;
}