题目连接:https://www.nowcoder.com/acm/contest/90/B
思路:首先根据题目意思很容易知道这棵树只有26种形态,我们可以处理出这26种形态,然后怎么去判断字典序呢,我们只用找到第一个不相同的位置就行,然后用lca去判断,着不同的位置可以二分找,也可以直接lca找,判断相等用hash即可,这道题十分毒瘤,相同的代码能相差六七百毫秒,能剪枝的就剪把
accode
#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
#define ULL unsigned long long
using namespace std;
const int maxn = 1e5+5;
const LL mod = 998244353;
LL S[28][maxn];
LL seed = 37;
int head[maxn];
int tot;
int n;
int Hash[maxn];
int depth[maxn];
int bz[maxn][19];
int a[maxn][28];
struct node
{
int v;
int net;
int k;
int va;
}E[maxn*2];
LL jz[maxn];
void init()
{
memset(head,-1,sizeof(head));
tot = 0;
}
void build(int u,int v,int va,int k)
{
E[tot].v = v;
E[tot].net = head[u];
E[tot].va = va;
E[tot].k = k;
head[u] = tot++;
}
void BZ()
{
for(int j = 1;j<19;j++){
for(int k = 1;k<=n;k++){
bz[k][j] = bz[bz[k][j-1]][j-1];
}
}
}
int getans(int u,int v,int t)
{
t = t%26;
if(S[t][u]==S[t][v]){
return 0;
}
for(int i = 18;i>=0;i--){
if(bz[u][i]==0||bz[v][i]==0) continue;
int uu = bz[u][i];
int vv = bz[v][i];
if((S[t][u]-S[t][uu]*jz[depth[u]-depth[uu]]%mod+mod)%mod==(S[t][v]-S[t][vv]*jz[depth[v]-depth[vv]]%mod+mod)%mod){
u = uu;
v = vv;
}
}
if(a[u][t]==a[v][t]){
if(bz[u][0]==0){
return -1;
}
else if(bz[v][0]==0){
return 1;
}
else{
u = bz[u][0];
v = bz[v][0];
}
}
if(a[u][t]!=a[v][t]){
if(a[u][t]<a[v][t]){
return -1;
}
else{
return 1;
}
}
else{
return 0;
}
}
void dfs1(int u,int fa,int deep)
{
depth[u] = deep;
bz[u][0] = fa;
for(int i = head[u];~i;i = E[i].net){
int v = E[i].v;
dfs1(v,u,deep+1);
}
}
void dfs(int u,int t,LL sum)
{
S[t][u] = sum;
for(int i = head[u];~i;i =E[i].net){
int v = E[i].v;
a[E[i].v][t] = (E[i].va+t*E[i].k)%26+1;;
dfs(v,t,(sum*seed+(E[i].va+t*E[i].k)%26+1)%mod);
}
}
struct node3
{
int id;
int u,v;
};
int ans[maxn];
vector<node3>Q[27];
int main()
{
int t;
scanf("%d",&t);
jz[0] = 1;
for(int i = 1;i<maxn;i++){
jz[i] = (jz[i-1]*seed)%mod;
}
while(t--){
init();
scanf("%d",&n);
for(int i = 2;i<=n;i++){
int p,k;
char s[2];
scanf("%d%s%d",&p,s,&k);
build(p,i,s[0]-'a',k);
}
dfs1(1,0,0);
BZ();
for(int i = 0;i<26;i++){
Q[i].clear();
}
int q;
scanf("%d",&q);
for(int i = 0;i<q;i++){
int u,v,tt;
scanf("%d%d%d",&u,&v,&tt);
tt %=26;
node3 tmp;
tmp.id = i;
tmp.u = u;
tmp.v = v;
Q[tt].push_back(tmp);
}
for(int i = 0;i<26;i++){
if(Q[i].size()==0) continue;
dfs(1,i,0);
for(int j = 0;j<Q[i].size();j++){
int tmp = getans(Q[i][j].u,Q[i][j].v,i);
ans[Q[i][j].id] = tmp;
}
}
for(int i = 0;i<q;i++){
if(ans[i]==-1){
puts("<");
}
else if(ans[i]==0){
puts("=");
}
else{
puts(">");
}
}
}
}
/*
链接:https://www.nowcoder.com/acm/contest/90/B
来源:牛客网
1 10 1 a 1 1 a 5 1 c 2 2 f 2 3 a 5 3 e 3 4 b 1 5 z 1 7 o 2 4 5 7 0 5 7 2 9 10 1 8 8 8*/