T1
#include <bits/stdc++.h>
using namespace std;
inline void read(int &x) {
char ch; while(!isdigit(ch=getchar()));
for(x=ch-'0'; isdigit(ch=getchar()); x=x*10+ch-'0');
}
const int MAXN = 200005;
int n, m, val[MAXN], cnt[MAXN], ans[MAXN], stk[MAXN], indx, now;
vector<int>e[MAXN];
int Mx, Id;
void ser(int u, int ff, int d) {
if(d > Mx) Mx = d, Id = u;
for(int i = e[u].size()-1, v; i >= 0; --i)
if((v=e[u][i]) != ff) ser(v, u, d+1);
}
int son[MAXN], mx1[MAXN], mx2[MAXN], dep[MAXN];
void dfs1(int u, int ff) {
dep[u] = dep[ff] + 1;
son[u] = mx1[u] = mx2[u] = 0;
for(int i = e[u].size()-1, v; i >= 0; --i)
if((v=e[u][i]) != ff) {
dfs1(v, u);
if(mx1[v] + 1 > mx1[u]) mx2[u] = mx1[u], mx1[u] = mx1[v] + 1, son[u] = v;
else if(mx1[v] + 1 > mx2[u]) mx2[u] = mx1[v] + 1;
}
}
inline void del() { if(!--cnt[val[stk[indx--]]]) --now; }
inline void ins(int x) { if(!(cnt[val[stk[++indx] = x]]++)) ++now; }
void dfs2(int u, int ff) {
if(son[u]) {
while(indx && dep[stk[indx]] >= dep[u] - mx2[u]) del();
ins(u); dfs2(son[u], u);
}
while(indx && dep[stk[indx]] >= dep[u] - mx1[u]) del();
ans[u] = max(ans[u], now);
for(int i = e[u].size()-1, v; i >= 0; --i)
if((v=e[u][i]) != ff && v != son[u]) {
if(stk[indx] != u) ins(u);
dfs2(v, u);
}
if(stk[indx] == u) del();
}
int main () {
freopen("star.in", "r", stdin);
freopen("star.out", "w", stdout);
read(n), read(m);
for(int i = 1, u, v; i < n; ++i)
read(u), read(v), e[u].push_back(v), e[v].push_back(u);
for(int i = 1; i <= n; ++i) read(val[i]);
ser(1, 0, 0);
int L = Id; Mx = 0;
ser(L, 0, 0);
int R = Id;
dfs1(L, 0); dfs2(L, 0);
while(indx) del();
dfs1(R, 0); dfs2(R, 0);
for(int i = 1; i <= n; ++i) printf("%d\n", ans[i]);
}
T2
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 200005;
struct SAM {
int fa[MAXN], len[MAXN], ch[MAXN][26];
int rt, tot, last;
SAM() { rt = tot = last = 1; len[0] = -1; }
inline void copy(int nq, int q) {
memcpy(ch[nq], ch[q], sizeof ch[q]);
fa[nq] = fa[q], len[nq] = len[q];
}
inline int ins(int x) {
int p = last, nw = ++tot;
len[nw] = len[last] + 1, last = nw;
while(p && !ch[p][x]) ch[p][x] = nw, p = fa[p];
if(!p) fa[nw] = rt;
else {
int q = ch[p][x];
if(len[p] + 1 == len[q]) fa[nw] = q;
else {
int nq = ++tot; copy(nq, q);
len[nq] = len[p] + 1, fa[q] = fa[nw] = nq;
while(p && ch[p][x] == q) ch[p][x] = nq, p = fa[p];
}
}
return nw;
}
}S1, S2;
char s[MAXN];
int n, pos1[MAXN], pos2[MAXN]; LL ans;
vector<int>G1[MAXN], G2[MAXN];
inline void link1(int u, int v) { G1[u].push_back(v), G1[v].push_back(u); }
inline void link2(int u, int v) { G2[u].push_back(v), G2[v].push_back(u); }
int dfn[MAXN], seq[MAXN<<1], dep[MAXN], cnt[MAXN], tmr;
int Lg[MAXN<<1], f[MAXN<<1][20];
void dfs1(int u, int ff) {
seq[dfn[u] = ++tmr] = u;
dep[u] = dep[ff] + 1;
for(int i = G2[u].size()-1, v; i >= 0; --i)
if((v=G2[u][i]) != ff) dfs1(v, u), seq[++tmr] = u;
cnt[u] = S2.len[u] + 1;
}
void getst() {
for(int i = 1; i <= tmr; ++i) f[i][0] = seq[i];
for(int i = 2; i <= tmr; ++i) Lg[i] = Lg[i>>1] + 1;
for(int j = 1; j < 20; ++j)
for(int i = 1; i+(1<<j)-1 <= tmr; ++i)
f[i][j] = dep[f[i][j-1]] < dep[f[i+(1<<j-1)][j-1]] ? f[i][j-1] : f[i+(1<<j-1)][j-1];
}
inline int LCA(int u, int v) {
int l = dfn[u], r = dfn[v];
if(l > r) swap(l, r);
int t = Lg[r-l+1];
return dep[f[l][t]] < dep[f[r-(1<<t)+1][t]] ? f[l][t] : f[r-(1<<t)+1][t];
}
int rt[MAXN], tot;
struct seg {
int ch[2], lx, rx; LL res;
}t[MAXN*30];
inline void upd(int i) {
t[i].lx = t[t[i].ch[0]?t[i].ch[0]:t[i].ch[1]].lx;
t[i].rx = t[t[i].ch[1]?t[i].ch[1]:t[i].ch[0]].rx;
t[i].res = t[t[i].ch[0]].res + t[t[i].ch[1]].res;
if(t[i].ch[0] && t[i].ch[1])
t[i].res -= cnt[LCA(seq[t[t[i].ch[0]].rx], seq[t[t[i].ch[1]].lx])];
}
int mg(int l, int r) {
if(!l || !r) return l + r;
t[l].ch[0] = mg(t[l].ch[0], t[r].ch[0]);
t[l].ch[1] = mg(t[l].ch[1], t[r].ch[1]);
upd(l); return l;
}
void insert(int &i, int l, int r, int x) {
if(!i) i = ++tot;
if(l == r) { t[i].lx = t[i].rx = x, t[i].res = cnt[seq[x]]; return; }
int mid = (l + r) >> 1;
if(x <= mid) insert(t[i].ch[0], l, mid, x);
else insert(t[i].ch[1], mid+1, r, x);
upd(i);
}
void dfs2(int u, int ff) {
for(int i = G1[u].size()-1, v; i >= 0; --i)
if((v=G1[u][i]) != ff) dfs2(v, u), rt[u] = mg(rt[u], rt[v]);
ans += t[rt[u]].res * (S1.len[u] - S1.len[ff]);
}
int main () {
freopen("sea.in", "r", stdin);
freopen("sea.out", "w", stdout);
scanf("%s", s+1); n = strlen(s+1);
for(int i= 1; i <= n; ++i) pos1[i] = S1.ins(s[i]-'a');
for(int i= n; i >= 1; --i) pos2[i] = S2.ins(s[i]-'a');
pos1[0] = pos2[n+1] = 1; ans = 1;
for(int i = 2; i <= S1.tot; ++i) link1(S1.fa[i], i), ans += S1.len[i]-S1.len[S1.fa[i]];
for(int i = 2; i <= S2.tot; ++i) link2(S2.fa[i], i);
dfs1(1, 0), getst();
for(int i = 1; i <= n; ++i) insert(rt[pos1[i-1]], 1, tmr, dfn[pos2[i+1]]);
dfs2(1, 0);
printf("%lld\n", ans);
}
T3
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
int n, m, c, fa[55], dp[55][2505], f[2505], pw[55], tot; char s[10][55];
struct node { LL s; int f[55]; }tmp;
vector<node>vec;
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void mg(int x, int y) { if(find(x) != find(y)) fa[find(y)] = find(x); }
void build(node x) {
for(int i = 1; i <= m; ++i) fa[i] = i;
for(int i = 1; i <= m; ++i) if(x.s>>i&1)
for(int j = 1; j <= i; ++j) mg(j, m-i+j);
}
bool chk(int x) {
build(tmp);
for(int i = x; i <= m; ++i)
if(!(tmp.s>>i&1)) {
bool flg = 0;
for(int j = 1; j <= i; ++j)
if(find(j) != find(m-i+j))
{ flg = 1; break; }
if(!flg) return 0;
}
return 1;
}
void dfs(int x) {
if(!x) {
build(tmp);
for(int i = 1; i <= m; ++i) tmp.f[i] = fa[i];
vec.push_back(tmp); return;
}
if(chk(x)) dfs(x-1); tmp.s ^= 1ll<<x;
if(chk(x)) dfs(x-1); tmp.s ^= 1ll<<x;
}
bool tag[55];
void solve(int x) {
for(int i = tot-1; i >= 0; --i) {
bool flg = 1;
for(int j = 1; flg && j <= m; ++j)
for(int k = j+1; flg && k <= m; ++k)
if(s[x][j] != '?' && s[x][k] != '?')
if(s[x][j] != s[x][k] && vec[i].f[j] == vec[i].f[k])
flg = 0;
if(!flg) f[i] = 0;
else {
for(int j = 1; j <= m; ++j) tag[j] = 0;
for(int j = 1; j <= m; ++j)
if(s[x][j] != '?') tag[vec[i].f[j]] = 1;
int cnt = 0;
for(int j = 1; j <= m; ++j)
if(j == vec[i].f[j] && !tag[j]) ++cnt;
f[i] = pw[cnt];
for(int j = i+1; j < tot; ++j)
if((vec[i].s & vec[j].s) == vec[i].s)
f[i] = (f[i] + mod - f[j]) % mod;
}
}
}
int main () {
freopen("wind.in", "r", stdin);
freopen("wind.out", "w", stdout);
scanf("%d%d%d", &n, &m, &c);
for(int i = 1; i <= n; ++i) scanf("%s", s[i]+1);
tmp.s ^= 1ll<<m, dfs(m-1); tot = vec.size();
pw[0] = 1;
for(int i = 1; i <= m; ++i) pw[i] = 1ll * pw[i-1] * (c+1) % mod;
dp[0][0] = 1;
for(int i = 1; i <= n; ++i) {
solve(i);
for(int j = 0; j < tot; ++j)
for(int k = 0; k <= j; ++k)
dp[i][j] = (dp[i][j] + 1ll * dp[i-1][k] * f[j]) % mod;
}
int ans = 0;
for(int i = 0; i < tot; ++i) ans = (ans + dp[n][i]) % mod;
printf("%d\n", ans);
}