Trie&可持久化

1.Trie

  • [POJ3764]The xor-longest Path
    题目大意:给出一棵有\(N\)个节点的树,树上每条边都有一个权值。从树中选择两个点\(x\)\(y\),把\(x\)\(y\)的路径上的所有边权\(xor\),求最大值(\(N\le {10}^5\)
    \(d[x]\)\(x\)到根的路径\(xor\),易得\(xor_{x->y}=d[x]\; xor\; d[y]\),问题就转化为求最大的\(d[x]\; xor\; d[y]\).
int ch[Maxm][2], cnt;
void cal(int x){
    int now=0, p=0;
    for(int j=30; j >= 0; j--){
        int k=(x&(1<<j)) ? 0 : 1;
        if(ch[now][k]) now=ch[now][k], p+=1<<j; 
        else if(ch[now][k^1]) now=ch[now][k^1];
        else break;
    }
    ans=max(ans, p);
}
void ins(int x){
    int now=0;
    for(int i=30, v; i >= 0; i--) v=(x&(1<<i)) ? 1 : 0, now=ch[now][v]=ch[now][v] ? ch[now][v] : ++cnt;
}
void dfs(int u, int fa){for(int i=head[u], v; i; i=nxt[i]) if((v=to[i]) != fa) d[v]=d[u]^w[i], dfs(v, u);}
void solve(){
    while(cin>>n){
        mem(head, 0); mem(nxt, 0); tot=0; mem(ch, 0); cnt=0; mem(d, 0); ans=0;
        for(int i=1, u, v, ww; i < n; i++) 
            u=read()+1, v=read()+1, ww=read(), add(u, v, ww), add(v, u, ww);
        dfs(1, 0); for(int i=1; i <= n; i++) ins(d[i]);
        for(int i=1; i <= n; i++) cal(d[i]);
        printf("%d\n", ans);
    }
}

2.可持久化

  • [BZOJ3261]最大异或和
    \(s[i]=xor_{j=1}^ia[j]\)\(a[p]\; xor\; a[p+1]\; xor ... xor\; a[N]\; xor\; x=s[p-1]\; xor\; s[N]\; xor \; x\)
    就是求\(p\in [l-1, r-1]\)\(s[p]\; xor\; s[N]\; xor\; x\)的最大值
    当只限制\(p \le r\)时, 只要在第\(r\)\(trie\)找就好了,而当限制\(l \le p\)时我们还要在\(trie\)的每个节点上记一个\(latest\),表示用了这个节点的最晚的\(s[i]\)的下标\(i\)
void ins(int x, int o, int p, int now){
    if(now < 0) {latest[o]=tot; return ;}
    int k=(x>>now)&1; if(p) ch[o][k^1]=ch[p][k^1];
    ch[o][k]=++cnt; ins(x, ch[o][k], ch[p][k], now-1); 
    latest[o]=max(latest[ch[o][0]], latest[ch[o][1]]);
}
int query(int L, int o, int x, int now){
    if(now < 0) return s[latest[o]]^x;
    int k=(x>>now)&1;
    if(latest[ch[o][k^1]] >= L) return query(L, ch[o][k^1], x, now-1);
    return query(L, ch[o][k], x, now-1);
}
void solve(){
    n=read(), m=read(); latest[0]=-1; rt[0]=++cnt; ins(0, rt[0], 0, 23);
    for(int i=1, x; i <= n; i++) x=read(), rt[i]=++cnt, ++tot, s[i]=s[i-1]^x, ins(s[i], rt[i], rt[i-1], 23);
    for(int i=1; i <= m; i++){
        char cmd=getchar(); while(cmd != 'Q' && cmd != 'A') cmd=getchar();
        if(cmd == 'Q') {
            int l=read(), r=read(), x=read(), mx=query(l-1, rt[r-1], x^s[tot], 23);
            printf("%d\n", mx); 
        }
        else ++tot, rt[tot]=++cnt, s[tot]=s[tot-1]^read(), ins(s[tot], rt[tot], rt[tot-1], 23);
    }
}

猜你喜欢

转载自www.cnblogs.com/zerolt/p/9292622.html