# 2018 计蒜之道 初赛 第二场（字典树）

**

## C题 阿里巴巴的手机代理商（中等）

**

bool contains(char s1[], char s2[]) {
int len1 = strlen(s1);
int len2 = strlen(s2);
int i = len1 - 1, j = len2 - 1;
if (len1 >= len2)
return false;
while (j >= 0) {
if (i < 0)
return true;
if (s1[i] != s2[j])
return false;
i--;
j--;
}
}

int update_insert(char s2[], int len1, int endd, bool contain) {
int len2 = strlen(s2);
ll val = num[endd];
int now = 0;
int start = len2 - 1;
int save = ztree[endd][s2[len2 - len1 - 1] - 'a'];
for (int i = start; i >= 0; i--) {
if (contain && i <= len2 - len1 - 1 || ztree[now][s2[i] - 'a'] == 0)
ztree[now][s2[i] - 'a'] = cnt++;
now = ztree[now][s2[i] - 'a'];
num[now] += val;
}
for (int i = 0; i < 26; i++) {
if (ztree[endd][i]) {
ztree[now][i] = ztree[endd][i];
num[ztree[now][i]] = num[ztree[endd][i]];
}
}
if (contain) {
ztree[now][s2[len2 - len1 - 1] - 'a'] = save;
num[ztree[now][s2[len2 - len1 - 1] - 'a']] = num[save];
}
return ztree[endd][s2[len2 - len1 - 1] - 'a'];
}

void update_del(char s1[], ll val) {
int len1 = strlen(s1);
int now = 0;
int aa = 0;
for (int i = len1 - 1; i >= 0; i--) {
de[aa][0] = now;
de[aa++][1] = s1[i] - 'a';
now = ztree[now][s1[i] - 'a'];
num[now] -= val;
}
de[aa++][0] = now;
for (int i = 0; i < aa - 1; i++) {
if (num[de[i + 1][0]] == 0)
ztree[de[i][0]][de[i][1]] = 0;
}
for (int i = 0; i < 26; i++) {
ztree[now][i] = 0;
}
}

void update(char s1[], char s2[]) {
bool con = contains(s1, s2);
int endd = query(s1);
ll val = num[endd];
int connect = update_insert(s2, strlen(s1), endd, con);
update_del(s1, val);
if (con)
ztree[endd][s2[strlen(s2) - strlen(s1) - 1] - 'a'] = connect;
}

**

## D题 阿里巴巴的手机代理商（困难）

**

struct VQ {
int dirV;
int id;
string qstring;
}vquery[1000005];

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120