比赛过程
7:30 am
又是HEOI2012? 上次才考过Day1的. 浏览了一遍题… t2不是那个sb题吗??? wys昨晚才写了我没选择去看hh. 但是解法显然fail树上lca呵呵. 看一下t1, t3. t1又是数学? t3感觉像是搜索. 先想一下这两道吧.
8:30 am
woc第一题样例260我怎么算不出来??不是5 * 4 * 4 * 4的320吗?260还是13的倍数? 13是怎么来的? 难不成不是普通的相乘还要有加法? 想了半天再看看那个图觉得没有问题. 抱着一股怨气去看了t3. 怎么我又看不懂题?? 不是每次只能往一个方向走吗? 我怎么知道他要选哪条? 还问我第i天他能走多少? 我怎么知道??? 至此我已经严重怀疑出题人的语文水平…好歹我停课了语文也进过年级前十的好吧. 弃了弃了. 先去码第二题吧.
9:30 am
t2半个多小时就码出来了… 调了几下过了样例. 看一下t1, 我试着每个单位横着放像====这样的形式算一下– woc就是260? md为什么题面的图是||||这样的啊, 如果这样限制关系就少了. 推了一下式子发现可以nlogm的做, 先敲个暴力拿25pts算了. 再去看看第三题.
10:30 am
woc我要给出题人寄刀片!!!. 还是读不懂t3啊QAQ. 算了时间不多还是再在t1找点部分分. 突然发现t1最后一个点p只有3000? 这不就有循环节然后是个等比数列求和? 发现没有逆元只能矩阵快速幂求和gg… 这玩意还没敲过… 不过还有一个小时慢慢来吧.
11:30am
写完再复查了t2, 考试结束.
赛后
怎么只有25分??? QAQ第二题文件好像又交错… 重交的时候现在bzoj上交了一下, 发现最后几个点要mle, 精准算了一下空间, 重交就A了. 唉算了这次就当考起耍吧, t1矩阵快速幂好像还是写挂了… 上次欢乐AK这次就惨痛爆零啊… 以后文件再交错我就直播吃翔. 不过qjx他们题也没读懂… 看来不是我的问题嘛233. 不过到我省选的时候要是读不懂题就是要崩溃了.
暂时只有t2的代码啦.
#include<bits/stdc++.h>
using namespace std;
const int P = 20;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 5;
queue<int> q;
char str[maxn];
int num, tot, sz, n, m;
int c[maxn][26], fail[maxn << 1];
int anc[maxn][P + 1], ans[maxn], dep[maxn << 1];
int bin[maxn << 1], id[maxn << 1], bef[maxn << 1];
inline void init() {
bin[0] = 1;
for (int i = 1; i <= 20; ++ i)
bin[i] = bin[i - 1] << 1;
}
inline void insert(char *ss) {
int p = 0;
for (int i = 0; ss[i]; ++ i) {
int index = ss[i] - 'a';
if (!c[p][index]) {
c[p][index] = ++ tot;
ans[tot] = (1ll * index + 1ll * ans[p] * 26) % mod;
}
p = c[p][index];
id[++ sz] = p;
}
}
inline void getfail() {
for (int i = 0; i < 26; ++ i)
if (c[0][i]) q.push(c[0][i]), dep[c[0][i]] = 1;
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i = 1; i < P && dep[u] >= bin[i]; ++ i)
anc[u][i] = anc[anc[u][i - 1]][i - 1];
for (int i = 0; i < 26; ++ i) {
if (c[u][i]) {
fail[c[u][i]] = c[fail[u]][i];
anc[c[u][i]][0] = fail[c[u][i]];
dep[c[u][i]] = dep[fail[c[u][i]]] + 1, q.push(c[u][i]);
} else c[u][i] = c[fail[u]][i];
}
}
}
inline int query(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
int t = dep[u] - dep[v];
for (int i = 0; i < P; ++ i)
if (t & bin[i]) u = anc[u][i];
for (int i = P - 1; ~i; -- i)
if (anc[u][i] != anc[v][i])
u = anc[u][i], v = anc[v][i];
return (u == v) ? u : anc[u][0];
}
int main() {
init();
scanf("%d", &n);
for (int i = 1; i <= n; ++ i)
bef[i] = sz, scanf("%s", str), insert(str);
getfail();
scanf("%d", &m);
for (int i = 1; i <= m; ++ i) {
int x, y, k, l;
scanf("%d%d%d%d", &x, &y, &k, &l);
x = id[bef[x] + y], k = id[bef[k] + l];
printf("%d\n", ans[query(x, k)]);
}
}