注意!!!代码是没有ac的老是re我也不知道为什么以后来修改。。。。
//考虑暴力做法先找出有s1为前缀的串,然后在这些串里有哪些后缀有s2即是了。
//这就像区间第k大,先找出题目要求的某个区间,然后用可持久化的方法求第k大。
//所以我们这用可持久化trie.注意我们是用dfs顺序构造的可持久话trie树即是字符串的字典序。字典序相近的在一起。因为我们要找出有s1前缀的那些区间。很明显这些区间的字符串的字典序
//是相近的吧,因为都已s1为前缀啊
//dfs构造时其中用到了dfs的括号性(好像是这么叫)具体看算法导论.
/*#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
char ss[2000010];//原串输入
char ss1[2000010], ss2[2000010];
struct trienode
{
char value;
int son[26];
int times;//有多少次到此点
int begin, end;//用于可持久化利用dfs的括号性质记录根节点范围
};
struct longertrienode
{
char value;
int son[26];
int times;
};
int root, all=1;//root 代表trie的根
int roots[2001000];//roots代表可持久化trie树的各种根
int tot = 1;//记录trie的节点
int ltot = 1;//记录ltrie的节点
trienode trietree[2000010];
longertrienode ltrietree[2000010];
char stack[2000010];
int top = 0;//记录栈的顶
void insert(char *s)//构造trie
{
int len = strlen(s);
int temp = root;
for (int i = 0; i < len; i++)
{
if (trietree[temp].son[s[i] - 'a'] == 0)
trietree[temp].son[s[i] - 'a'] = tot++;
temp = trietree[temp].son[s[i] - 'a'];
trietree[temp].value = s[i];
if (i == len - 1)trietree[temp].times++;
}
}
int longerinsert(int left, int num,int numm)//构造可持久化trie,要保证ltrietree[0]的所有变量都为0,woc此题不能用dfs应为英文字太多会爆。。。。我日~~~~~~
{
char k = 'a';
int temp = ltot++;
int returntemp = temp;
for (int i = left; i > 0; i--)
{
ltrietree[temp].value = stack[i];
ltrietree[temp].times = ltrietree[num].times + numm;
for (int j = 0; j < 26; j++)
{
if (ltrietree[num].son[j] && (k + j) != stack[i - 1])
ltrietree[temp].son[j] = ltrietree[num].son[j];
else
{
if ((k + j) == stack[i - 1])
ltrietree[temp].son[j] = ltot++;
}
}
temp = ltrietree[temp].son[stack[i - 1] - 'a']; num = ltrietree[num].son[stack[i - 1] - 'a'];
}
return returntemp;
}
void orderdfs(int &num)//dfs构造
{
stack[top++] = trietree[num].value;
trietree[num].begin = all - 1;
if (trietree[num].times)
{
roots[all]=longerinsert(top,roots[all-1], trietree[num].times);//从top开始让根是0
//travel(roots[all]);//测试
all++;
}
for (int i = 0; i < 26; i++)
{
if (trietree[num].son[i])
orderdfs(trietree[num].son[i]);
}
top--;
trietree[num].end = all - 1;
}
int findtrie(char *s)
{
int temp = root;
int len = strlen(s);
for (int i = 0; i < len; i++)
{
temp = trietree[temp].son[s[i] - 'a'];
if (!temp)return 0;
}
return temp;
}
int findltrie(int num,char *s)
{
int temp = roots[num];
int len = strlen(s);
for (int i = 0; i < len; i++)
{
temp = ltrietree[temp].son[s[i] - 'a'];
if (!temp)return 0;
}
return ltrietree[temp].times;
}
int main()
{
int n;
scanf("%d", &n);
getchar();
while (n--)
{
int i;
for (i = 0;; i++)
{
ss[i] = getchar();
if (ss[i] == '\n')break;
}
ss[i] = '\0';
//cout << ss << endl;
insert(ss);
}
orderdfs(root);
int m;
scanf("%d", &m);
int ans = 0;
getchar();
while (m--)
{
int i, k;
for ( i = 0;; i++)
{
ss[i] = getchar();
if(ss[i] == '\n')
break;
}
ss[i] = '\0';
//cout << ss << endl;
int len = strlen(ss);
//cout << ss<< endl;
for ( i = 0; ss[i] != ' '; i++)
ss1[i] = (ss[i]-'a'+ans)%26+'a';
ss1[i] = '\0';
for (i = len - 1, k = 0; ss[i] != ' '; i--, k++)
ss2[k] = (ss[i] - 'a' + ans) % 26 + 'a';
ss2[k] = '\0';
int k1 = findtrie(ss1);
if (k1 == 0)
{
ans = 0;
printf("%d\n", ans);
}
else
{
int beginn = trietree[k1].begin; int end = trietree[k1].end;
ans = findltrie(end,ss2)-findltrie(beginn,ss2);
printf("%d\n", ans);
}
}
return 0;
}*/
网上大部分题解如果dfs没用非递归的话都是有问题的如果我只有一个串然后这个串长为2000000那么就只有爆栈了所以留坑以后来写吧我还太弱了写不了。。。。。