hdu 4601 Letter Tree 线段树

本文详细解析并实现了特定C++函数的优化策略,通过使用预处理指令、模板元编程和高效的数据结构,显著提高了代码的执行效率。文中包括了实例代码演示、性能对比和优化后的具体效果,旨在为C++开发者提供实用的性能优化技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define ls rt<<1
#define rs rt<<1|1
#define Mid int m = (l + r) >> 1;
#define X first
#define Y second
const int mod = 1e9 + 7;
const int maxn = 100005;
typedef long long LL;
typedef pair<int, int> PII;
LL _26[maxn];
void init() {
    int i;
    _26[0] = 1;
    for (i = 1; i < maxn; i++)
        _26[i] = _26[i - 1] * 26 % mod;
}

struct Edge {
    int v, w, next;
    Edge(int v, int w, int next) :
            v(v), w(w), next(next) {
    }
    Edge() {
    }
} edge[maxn << 2];
int n, m;
int head[maxn], E;

void add(int s, int t, int w) {
    edge[E] = Edge(t, w, head[s]);
    head[s] = E++;
    edge[E] = Edge(s, w, head[t]);
    head[t] = E++;
}

vector<int> res[maxn];
int val[maxn], pos[maxn], dep[maxn], dfn[maxn];
int len[maxn], max_d[maxn], sum[maxn], rk[maxn];
int Time;
void edge_init() {
    int i;
    E = 0;
    memset(head, -1, sizeof(head));

}

struct trie {
    int ch[maxn][26], RK[maxn], sz;
    int newNode() {
        memset(ch[sz], 0, sizeof(ch[sz]));
        RK[sz] = 0;
        return sz++;
    }
    void dfs(int u, int fa, int rt) {
        dfn[u] = ++Time;
        max_d[u] = dep[u] = dep[fa] + 1;
        res[dep[u]].push_back(dfn[u]);
        pos[u] = res[dep[u]].size();
        int i, v, w;
        for (i = head[u]; ~i; i = edge[i].next) {
            v = edge[i].v;
            w = edge[i].w;
            if (v == fa) continue;
            val[v] = ((LL) val[u] * 26 + w) % mod;
            if (!ch[rt][w]) ch[rt][w] = newNode();
            dfs(v, u, ch[rt][w]);
            max_d[u] = max(max_d[u], max_d[v]);
        }
    }
    void bfs(){
        int id = 1, i;
        queue <int> q;
        q.push(0);
        RK[0] = 1;
        while(!q.empty()) {
            int u = q.front(); q.pop();
            for(i = 0; i < 26; i++) {
                int v = ch[u][i];
                if(v) {
                    RK[v] = ++id;
                    q.push(v);
                }
            }
        }
    }
    void cal(int u, int fa, int rt) {
        int i, v, w;
        for(i  = head[u]; ~i; i = edge[i].next) {
            v = edge[i].v;
            w = edge[i].w;
            if(v == fa) continue;
            rk[v] = RK[ch[rt][w]];
            cal(v, u, ch[rt][w]);
        }
    }
    void gao() {
        sz = 0;
        newNode();
        Time = 0;
        max_d[1] = dep[1] = 1;
        val[1] = 0;
        for (int i = 0; i <= n; i++)
            res[i].clear();
        dfs(1, 0, 0);
        bfs();

        rk[1] = 1;
        cal(1, 0, 0);
    }
} trie;

struct segtree {
    PII sum[maxn << 2];
    void pushUp(int rt) {
        sum[rt] = max(sum[ls], sum[rs]);
    }
    void insert(int p, int idx, int v, int l = 1, int r = n, int rt = 1) {
        if (l == r) {
            sum[rt] = make_pair(v, idx);
            return;
        }
        Mid
        ;
        if (p <= m)
            insert(p, idx, v, lson);
        else
            insert(p, idx, v, rson);
        pushUp(rt);
    }
    PII query(int L, int R, int l = 1, int r = n, int rt = 1) {
        if (L <= l && r <= R)
            return sum[rt];
        Mid
        ;
        PII ret = make_pair(-1, -1);
        if (L <= m)
            ret = max(ret, query(L, R, lson));
        if (R > m)
            ret = max(ret, query(L, R, rson));
        return ret;
    }
    void print(int l=1, int r=n, int rt=1) {
        if(l ==r) {
            printf("~~~~~%d %d\n", sum[rt].first, sum[rt].second);
            return;
        }
        Mid;
        print(lson);
        print(rson);
    }
} T;
void debug() {
    int i;
    for(i = 1; i <= n; i++)
        printf("%d ", rk[i]);
    puts("");
}
void solve() {
    int i;
    trie.gao();
    sum[0] = 0;
    for (i = 1; i <= n; i++)
        sum[i] = sum[i - 1] + res[i].size();
    for (i = 1; i <= n; i++)
        sum[i] -= res[i].size();
    for (i = 1; i <= n; i++) {
        int x = sum[dep[i]] + pos[i];
        T.insert(x, i, rk[i]);
    }
}

char buf[4];
int x, y, z;
int main() {

    //   freopen("1002.in", "r", stdin);
    //   freopen("my1002.out", "w", stdout);
    int i, j, cas;
    init();
    scanf("%d", &cas);
    while (cas--) {
        scanf("%d", &n);
        edge_init();
        for (i = 1; i < n; i++) {
            scanf("%d%d%s", &x, &y, buf);
            z = buf[0] - 'a';
            add(x, y, z);
        }

        solve();
    //    debug();
    //    T.print();
        scanf("%d", &m);
        int u, step;

        while (m--) {
            scanf("%d%d", &u, &step);
            if (!step) {
                puts("0");
                continue;
            }
            int q_dep = step + dep[u];
            if (max_d[u] < q_dep)
                puts("IMPOSSIBLE");
            else {

                int ldfn = res[dep[u]][pos[u] - 1];
                int rdfn;
                if (pos[u] == (int) res[dep[u]].size())
                    rdfn = n + 1;
                else
                    rdfn = res[dep[u]][pos[u]];

                int l = lower_bound(res[q_dep].begin(), res[q_dep].end(), ldfn)
                        - res[q_dep].begin() + 1;
                int r = lower_bound(res[q_dep].begin(), res[q_dep].end(), rdfn)
                        - res[q_dep].begin();

                l += sum[q_dep];
                r += sum[q_dep];
            //    printf("l = %d r = %d\n", l, r);
                int ans = (val[T.query(l, r).second]
                        - (LL) val[u] * _26[step] % mod) % mod;
                if (ans < 0)
                    ans += mod;
                printf("%d\n", ans);
            }
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值