广工校赛B.跳一跳,很简单的(hash+二分+lca)

题目连接: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*/

猜你喜欢

转载自blog.csdn.net/w571523631/article/details/79707617
今日推荐