[A through study notes] trie with 0-1 Trie

Trie root node to each of the original prefix string corresponds to a set, composed of a prefix letter corresponding to all the sides of the transfer path. We can maintain some of the required information for each node, so that can do a lot of things.

# 10049. "2.3 cases through a 1" Phone List

#include <bits/stdc++.h>
using namespace std;

namespace Trie {
    struct Node {
        Node *ch[10];
        int val;
        Node* clear() {
            for(int i=0;i<10;i++) ch[i]=NULL;
            val=0;
            return this;
        }
    };

    Node *root;
    Node pool[1000005];
    int ind=0;
    Node* newnode() {
        return pool[ind++].clear();
    }

    void clear() {
        ind=0;
        root=newnode();
    }
    void insert(string s) {
        Node *pos=root;
        for(int i=0;i<s.length();i++) {
            if(pos->ch[s[i]]==NULL) pos->ch[s[i]]=newnode();
            pos->val++;
            pos=pos->ch[s[i]];
        }
    }
    int query(string s) {
        Node *pos=root;
        for(int i=0;i<s.length();i++) {
            if(pos->ch[s[i]]==NULL) return 0;
            pos=pos->ch[s[i]];
        }
        return pos->val;
    }

    string str[10005];

    void solve() {
        int n;
        cin>>n;
        clear();
        for(int i=1;i<=n;i++) {
            cin>>str[i];
            for(int j=0;j<str[i].length();j++) str[i][j] -= '0';
            insert(str[i]);
        }
        int flag=0;
        for(int i=1;i<=n;i++) {
            if(query(str[i])) {
                flag=1;
                break;
            }
        }
        if(flag) cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
}

int main() {
    int t;
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--) Trie::solve();
    return 0;
}

# 10050. "2.3 cases through a 2" The XOR Largest Pair

0-1 Trie cases are typically used when XOR related issues, the idea is to record all 01 strings, we find the largest XOR can be greedy and from high to low, then Trie role in the current prefix is ​​already selected next, enables bitwise exclusive or is considering whether there is a suffix.

#include <bits/stdc++.h>
using namespace std;

namespace Trie {
struct Node {
    Node *ch[2];
    Node *clear() {
        ch[0] = ch[1] = 0;
        return this;  // Don't forget this
    }
};
Node *root;
Node pool[4000005];
int ind;
Node *newnode() { return pool[ind++].clear(); }
void insert(int x) {
    Node *pos = root;
    for (int i = 30; i >= 0; --i) {
        int b = (x / (1 << i)) & 1;
        if (pos->ch[b] == NULL)
            pos->ch[b] = newnode();
        pos = pos->ch[b];
    }
}
int query(int x) {
    Node *pos = root;
    int ans = 0;
    for (int i = 30; i >= 0 && pos != NULL; --i) {
        int b = (x / (1 << i)) & 1;
        if (pos->ch[b ^ 1] != NULL)
            pos = pos->ch[b ^ 1], ans += (1 << i);
        else
            pos = pos->ch[b];
    }
    return ans;
}
int a[1000005];
void solve() {
    int n, ans = 0;
    cin >> n;
    root = newnode();  // Don't forget this
    for (int i = 1; i <= n; i++) cin >> a[i], insert(a[i]);
    for (int i = 1; i <= n; i++) ans = max(ans, query(a[i]));
    cout << ans << endl;
}
}  // namespace Trie

int main() {
    ios::sync_with_stdio(false);
    Trie::solve();
}

# 10051. "2.3 cases through a 3" Nikitosh and XOR

See this formula we can easily think prefixes and transformation. Problem and minimize the s [r1] ^ s [l1-1] + s [r2] ^ s [l2-1] maximum.

Due to r1 <l2, it may be considered to deal with a prefix and a suffix max max, and then enumerate the demarcation point. The answer is

Max{pre[i]+suf[i+1]}

#include <bits/stdc++.h>
using namespace std;

namespace Trie {
struct Node {
    Node *ch[2];
    Node *clear() {
        ch[0] = ch[1] = 0;
        return this;  // Don't forget this
    }
};
Node *root;
Node pool[8000005];
int ind;
Node *newnode() { return pool[ind++].clear(); }
void insert(int x) {
    Node *pos = root;
    for (int i = 30; i >= 0; --i) {
        int b = (x / (1 << i)) & 1;
        if (pos->ch[b] == NULL)
            pos->ch[b] = newnode();
        pos = pos->ch[b];
    }
}
int query(int x) {
    Node *pos = root;
    int ans = 0;
    for (int i = 30; i >= 0 && pos != NULL; --i) {
        int b = (x / (1 << i)) & 1;
        if (pos->ch[b ^ 1] != NULL)
            pos = pos->ch[b ^ 1], ans += (1 << i);
        else
            pos = pos->ch[b];
    }
    return ans;
}
int a[1000005], pre[1000005], suf[1000005];
void solve() {
    int n, ans = 0;
    cin >> n;
    root = newnode();  // Don't forget this
    for (int i = 1; i <= n; i++) cin >> a[i], insert(a[i]), pre[i] = max(pre[i - 1], query(a[i]));
    ind = 0;
    root = newnode();
    reverse(a + 1, a + n + 1);
    for (int i = 1; i <= n; i++) insert(a[i]), suf[i] = max(suf[i - 1], query(a[i]));
    reverse(suf + 1, suf + n + 1);
    for (int i = 1; i < n; i++) ans = max(ans, pre[i] + suf[i + 1]);
    cout << ans << endl;
}
}  // namespace Trie

int main() {
    ios::sync_with_stdio(false);
    Trie::solve();
}

# 10052. "A 1 through 2.3 Exercise" Immediate Decodability

And in front of the same questions that

#include <bits/stdc++.h>
using namespace std;

namespace Trie {
struct Node {
    Node *ch[2];
    int val;
    Node *clear() {
        for (int i = 0; i < 2; i++) ch[i] = NULL;
        val = 0;
        return this;
    }
};

Node *root;
Node pool[1000005];
int ind = 0;
Node *newnode() { return pool[ind++].clear(); }

void clear() {
    ind = 0;
    root = newnode();
}
void insert(string s) {
    Node *pos = root;
    for (int i = 0; i < s.length(); i++) {
        if (pos->ch[s[i]] == NULL)
            pos->ch[s[i]] = newnode();
        pos->val++;
        pos = pos->ch[s[i]];
    }
}
int query(string s) {
    Node *pos = root;
    for (int i = 0; i < s.length(); i++) {
        if (pos->ch[s[i]] == NULL)
            return 0;
        pos = pos->ch[s[i]];
    }
    return pos->val;
}

string str[10005];

bool solve(int t) {
    clear();
    int n = 0;
    while (cin >> str[++n]) {
        if (str[n][0] == '9')
            break;
        for (int j = 0; j < str[n].length(); j++) str[n][j] -= '0';
        insert(str[n]);
    }
    --n;
    if (n <= 0)
        return false;
    int flag = 0;
    for (int i = 1; i <= n; i++) {
        if (query(str[i])) {
            flag = 1;
            break;
        }
    }
    if (flag)
        cout << "Set " << t << " is not immediately decodable" << endl;
    else
        cout << "Set " << t << " is immediately decodable" << endl;
    return true;
}
}  // namespace Trie

int main() {
    int t = 0;
    ios::sync_with_stdio(false);
    while (Trie::solve(++t))
        ;
    return 0;
}

# 10053. "One through 2.3 Exercise 2" L Language

We recorded u [i] article represent each prefix s [1..i] whether can be understood. Make a deal similar to the dp.

Forget the beginning of a long-reference T ......

#include <bits/stdc++.h>
using namespace std;

char buf[1000005];

void readstr(string &tar) {
    scanf("%s", buf);
    tar = buf;
}

int __cnt = 0;

namespace Trie {
struct Node {
    Node *ch[26];
    int val;
    Node *clear() {
        for (int i = 0; i < 26; i++) ch[i] = NULL;
        val = 0;
        return this;
    }
};

Node *root;
Node pool[5000005];
int u[1000005];
int ind = 0, ans = 0;
Node *newnode() { return pool[ind++].clear(); }

void clear() {
    ind = 0;
    root = newnode();
}
void insert(string &s) {
    Node *pos = root;
    for (int i = 0; i < s.length(); i++) {
        if (pos->ch[s[i]] == NULL)
            pos->ch[s[i]] = newnode();
        pos = pos->ch[s[i]];
    }
    pos->val++;
}
void query(string &s, int start) {
    Node *pos = root;
    int len = s.length();
    for (int i = start; i < len; i++) {
        __cnt++;
        if (pos->ch[s[i]] == NULL)
            return;
        pos = pos->ch[s[i]];
        if (pos->val)
            u[i + 1] = 1, ans = max(ans, i + 1);
    }
}

string str[1005];
string art;

void solve() {
    int n, m;
    scanf("%d%d", &n, &m);
    clear();
    for (int i = 1; i <= n; i++) {
        readstr(str[i]);
        for (int j = 0; j < str[i].length(); j++) str[i][j] -= 'a';
        insert(str[i]);
    }
    for (int i = 1; i <= m; i++) {
        ans = 0;
        memset(u, 0, sizeof u);
        readstr(art);
        int len = art.length();
        for (int j = 0; j < len; j++) art[j] -= 'a';
        u[0] = 1;
        for (int j = 0; j < len; j++) {
            if (u[j] == 0)
                continue;
            query(art, j);
        }
        cout << ans << endl;
    }
}
}  // namespace Trie

int main() {
    int t;
    ios::sync_with_stdio(false);
    Trie::solve();
    // cout<<__cnt<<endl;
    return 0;
}

# 10054. "2.3 exercise through a 3" Secret Message secret information

Information to build Trie, is still marking on the end point of each string. The result is equivalent to running up lost password string, numerals and marks, plus eventually stopped at the nodes on the running path (if the entire password is successfully matched string) and sub-tree. Before a direct recording, the prefix tree and after pretreatment with a click.

#include <bits/stdc++.h>
using namespace std;

namespace Trie {
struct Node {
    Node *ch[2];
    int val, sum;
    Node *clear() {
        for (int i = 0; i < 2; i++) ch[i] = NULL;
        val = sum = 0;
        return this;
    }
};

Node *root;
Node pool[1000005];
int ind = 0;
Node *newnode() { return pool[ind++].clear(); }

void clear() {
    ind = 0;
    root = newnode();
}
void insert(int len) {
    Node *pos = root;
    for (int i = 0; i < len; i++) {
        int si;
        cin >> si;
        if (pos->ch[si] == NULL)
            pos->ch[si] = newnode();
        pos = pos->ch[si];
    }
    pos->val++;
}
void dfs(Node *p) {
    if (p == NULL)
        return;
    dfs(p->ch[0]);
    dfs(p->ch[1]);
    p->sum = p->val;
    if (p->ch[0])
        p->sum += p->ch[0]->sum;
    if (p->ch[1])
        p->sum += p->ch[1]->sum;
}
int query(int len) {
    Node *pos = root;
    int ans = 0;
    for (int i = 0; i < len; i++) {
        int si;
        cin >> si;
        ans += pos->val;
        if (pos->ch[si] == NULL) {
            for (int j = 1; j <= len - i - 1; j++) cin >> si;
            return ans;
        }
        pos = pos->ch[si];
    }
    return ans + pos->sum;
}

string str[10005];

void solve() {
    int m, n;
    cin >> m >> n;
    clear();
    for (int i = 1; i <= m; i++) {
        int len;
        cin >> len;
        insert(len);
    }
    dfs(root);
    for (int i = 1; i <= n; i++) {
        int len;
        cin >> len;
        cout << query(len) << endl;
    }
}
}  // namespace Trie

int main() {
    int t;
    ios::sync_with_stdio(false);
    Trie::solve();
    return 0;
}

 

# 10056. "One through 2.3 Exercise 5" The XOR-longest Path

After the prefix tree and directly into XOR XOR and maximum points. In fact Euler sequence can be.

#include <bits/stdc++.h>
using namespace std;

namespace Trie {
    struct Node {
        Node *ch[2];
        Node* clear() {
            ch[0]=ch[1]=0;
            return this; // Don't forget this
        }
    };
    Node *root;
    Node pool[4000005];
    int ind;
    Node* newnode() {
        return pool[ind++].clear();
    }
    void insert(int x) {
        Node *pos = root;
        for(int i=30;i>=0;--i) {
            int b=(x/(1<<i))&1;
            if(pos->ch[b]==NULL) pos->ch[b]=newnode();
            pos=pos->ch[b];
        }
    }
    int query(int x) {
        Node *pos = root;
        int ans = 0;
        for(int i=30;i>=0 && pos!=NULL;--i) {
            int b=(x/(1<<i))&1;
            if(pos->ch[b^1]!=NULL)
                pos=pos->ch[b^1], ans+=(1<<i);
            else pos=pos->ch[b];
        }
        return ans;
    }
    int a[1000005];
    void solve(int n) {
        int ans=0;
        root=newnode(); // Don't forget this
        for(int i=1;i<=n;i++) insert(a[i]);
        for(int i=1;i<=n;i++) ans=max(ans,query(a[i]));
        cout<<ans<<endl;
    }
}
int n,vis[1000005];
vector<pair<int,int> > g[1000005];

void dfs(int p) {
    vis[p]=1;
    for(int i=0;i<g[p].size();i++) {
        int q=g[p][i].first;
        if(vis[q]==0) {
            Trie::a[q]=Trie::a[p] ^ g[p][i].second;
            dfs(q);
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<n;i++) {
        int u,v,w;
        cin>>u>>v>>w;
        g[u].push_back(make_pair(v,w));
        g[v].push_back(make_pair(u,w));
    }
    dfs(1);
    Trie::solve(n);
}

 

Guess you like

Origin www.cnblogs.com/mollnn/p/11607187.html