[Trie tree theme]

[Map || trie] P2580 and he began naming the wrong

Topic background

XS school chemistry competition coach is a group of people fond of furnace slag.

He would rub furnace slag while the side that day he named successive points to a classmate twice, and then just to be passing principal meal is then found 欧拉欧拉欧 pull (For details, see the game has ended CON900).

Title Description

After that the principal mission appointed you as a detective, to record his attendance every day. Principals will be provided and the number of students chemistry competition list, and you need to tell the president he has no point the wrong name. (Why not just let him play hearth.)

Input Format

The first line an integer n, the number of people in the class. Next n lines, each line a string representation of the name (different from each other, and contain only lowercase letters, the length does not exceed 50). A first n + 2 rows integer m, represents the name of the coach reported. Subsequently m rows, each row represents the name of a string of packets coach (containing only lowercase letters, and a length of no more than 50).

Output Format

For the name of each coach reported, the output line. If the name is correct and is the first time, output "OK", if the name of the error, the output "WRONG", if the name is correct but not the first time, the output "REPEAT". (Not in quotes)

Sample input and output

Input # 1 copy

Output # 1 copy

Description / Tips

For 40% of the data, n≤1000, m≤2000;

For 70% of the data, n≤10000, m≤20000;

To 100% of the data, n≤10000, m≤100000.

T1 always send points.

Note that the opening size of the array problem

const int N=5e5+10;
char str[50+5];
int tree[N][26];
int idx;
int cnt[N];

inline void insert(char s[]){
    int p=0;
    for(int i=0;s[i];++i){
        int now=s[i]-'a';
        int &son=tree[p][now];
        if(!son)son=++idx;
        p=son;
    }
}

inline int query(char s[]){
    int p=0;
    for(int i=0;s[i];++i){
        int now=s[i]-'a';
        int &son=tree[p][now];
        if(!son)return 404;//WRONG
        p=son;
    }
    if(cnt[p])return 666;//REPEAT
    cnt[p]++;
    return 100;//OK
}

int main(){
    int n;rd(n);
    rep(i,1,n){
        scanf("%s",str);
        insert(str);
    }
    int q;rd(q);
    while(q--){
        scanf("%s",str);
        int ans=query(str);
        if(ans==404)puts("WRONG");
        else if(ans==666)puts("REPEAT");
        else if(ans==100)puts("OK");
    }
    return 0;
}
int n;
map<string,int>mp;
string s;

int main(){
    int n;rd(n);
    rep(i,1,n){
        cin>>s;
        mp[s]++;
    }
    int q;rd(q);
    while(q--){
        cin>>s;
        if(mp[s]==1){
            puts("OK");
            mp[s]++;
        }
        else if(mp[s]==0){
            puts("WRONG");
        }
        else 
            puts("REPEAT");
    }
    return 0;
}

【trie】Phone List

Description

Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let's say the phone catalogue listed these numbers:

  • Emergency 911
  • Alice 97 625 999
  • Bob 91 12 54 26

In this case, it's not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob's phone number. So this list would not be consistent.

Input

The first line of input gives a single integer, 1 ≤ t ≤ 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 ≤ n ≤ 10000. Then follows n lines with one unique phone number on each line. A phone number is a sequence of at most ten digits.

Output

For each test case, output "YES" if the list is consistent, or "NO" otherwise.

Sample Input

2
3
911
97625999
91125426
5
113
12340
123440
12345
98346

Sample Output

NO
YES

SOL:

A configuration == \ (Trie \) tree, the string length and then sorted in descending order, and then sequentially inserted. If the time of insertion \ (Trie \) node of the tree has not empty, then for a sub-string of the string ==

Header files Dafa is good!

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dwn(i,a,b) for(int i=(a);i>=(b);--i)
template <typename T>inline void rd(T &x){
    x=0;char c=getchar();int flag=0;
    while(!isdigit(c)){flag|=c=='-';c=getchar();}
    while(isdigit(c)){x=x*10+(c^48);c=getchar();}
    x=flag?-x:x;
}
#define mem(a,b) memset(a,b,sizeof(a))
#define ee(i,u) for(int i=head[u];i;i=e[i].next)
/******************************************** Header Template **********************************************/
const int N=1e4+10;
char str[N][10+5];
int tree[N*10][10+5];
int ans=0,idx;

struct zifu{
    int len,id;
    bool operator <(const zifu &rhs)const{
        return len>rhs.len;
    }
}a[N];

inline void insert(char s[]){
    int p=0;
    bool flag=0;
    for(int i=0;s[i];++i){
        int now=s[i]-'0';
        int &son=tree[p][now];
        if(!son){
            son=++idx;
            flag=1;
        }
        p=son;
    }
 //   printf("%d %s\n",flag,s);
    if(flag==0)ans=1;
 //   printf("ans=%d\n",ans);
}

int main(){
    int T;rd(T);
    while(T--){
        //多组数据初始化啊啊啊啊
        mem(tree,0);
        ans=0,idx=0;
        int n;rd(n);
        rep(i,1,n){
            scanf("%s",str[i]);
            a[i].len=strlen(str[i]),a[i].id=i;
        }
        sort(a+1,a+n+1);
        rep(i,1,n){
            insert(str[a[i].id]);
        }
        if(ans==1)puts("NO");
        else puts("YES");
    }
    return 0;
}

[] 01trie maximum of XOR

const int N=1e5+10,M=3e6+10;
int n;
int a[N];
int tree[M][2];
int idx;

inline void insert(int x){
    int p=0;
    dwn(i,30,0){
        int now=x>>i&1;
        int &son=tree[p][now];
        if(!son)son=++idx;
        p=son;
    }
}

inline int query(int x){
    int res=0,p=0;
    dwn(i,30,0){
        int now=x>>i&1;
        if(tree[p][!now]){
            p=tree[p][!now];
            res+=1<<i;
        }
        else 
            p=tree[p][now];
    }
    return res;
}

#undef int
int main(){
#define int long long
    rd(n);
    rep(i,1,n){
        rd(a[i]);
        insert(a[i]);
    }
    int ans=0;
    rep(i,1,n){
        ans=max(ans,query(a[i]));
    }
    printf("%lld\n",ans);
    return 0;
}

[01trie || XOR tree edge weight value XORed} longest path

Given a tree, the tree has the edge weights.

XOR tree path length is defined as the XOR and the weights of all edges on the path:

formula.png

⊕ is XOR symbol.

To a tree with n nodes given above, you can find a different path or maximum length of it?

Input Format

The first row contains an integer n, the number of nodes of the tree.

Next, n-1 rows, each row comprising three integers u, v, W, expressed between node u and node v an edge weight is w.

Output Format

Output an integer, represents the maximum path length XOR XOR and maximum.

data range

1≤n≤1000001≤n≤100000,
0≤u,v<n0≤u,v<n,
0≤w<2310≤w<231

Sample input:

4
0 1 3
1 2 4
1 3 6

Sample output:

7

Sample interpretation

Sample XORed longest path should 0-> 1-> 2, value of 7 (= 3 ⊕ 4)

Differences of the tree or the values ​​may first pre-Val [u] represents a node u to the root of the exclusive-OR of the right side (pretreated with dfs out again), we ask if (u, V) path XORed directly val [u] ^ val [v] like (according to the nature of the exclusive oR, XOR They lca to the value of the root becomes 0).

The problem is converted into 1 ~ n val [i], the optional two val [i] such that the maximum value They XOR.

Is not that a question on it.

const int N=1e5+10;
int n,idx;
int val[N];
int tree[N*30][2];//N个数,每个数可能有30个子节点,值可能有两种情况:0/1

struct edge{
    int v,w,next;
}e[N<<1];

int head[N],edge_num;
inline void adde(int u,int v,int w){
    e[++edge_num].v=v;
    e[edge_num].w=w;
    e[edge_num].next=head[u];
    head[u]=edge_num;
}

inline void dfs(int u,int fa){
    ee(i,u){
        int v=e[i].v,w=e[i].w;
        if(v==fa)continue;
        val[v]=val[u]^w;
        dfs(v,u);
    }
}

inline void insert(int x){
    int p=0;
    dwn(i,30,0){
        int now=x>>i&1;
        int &son=tree[p][now];
        if(!son)son=++idx;
        p=son;
    }
}

inline int query(int x){
    int res=0,p=0;
    dwn(i,30,0){
        int now=x>>i&1;
        if(tree[p][!now]){
            p=tree[p][!now];
            res+=1<<i;
        }
        else 
            p=tree[p][now];
    }
    return res;
}

int main(){
    rd(n);
    rep(i,1,n-1){
        int u,v,w;rd(u),rd(v),rd(w);
        adde(u,v,w),adde(v,u,w);
    }
    dfs(0,-1);
    rep(i,1,n){
        insert(val[i]);
    }
    int ans=0;
    rep(i,1,n)
        ans=max(ans,query(val[i]));
    printf("%d\n",ans);
    return 0;
}

[142] trie prefix statistics,

Given N strings S1, S2 ... SNS1, S2 ... SN, M times the next inquiry, each time a given query string T, seeking S1S1 ~ SNSN how many T is a prefix of string.

The total length of the input string is not more than 106,106, containing only lowercase letters.

Input Format

The first line of the input two integers N, M.

Next N lines of input string SiSi.

Next, a string of M lines each T for interrogation.

Output Format

For each inquiry, output a integer answer.

Each answer per line.

Sample input:

3 2
ab
bc
abc
abc
efg

Sample output:

2
0
const int N=1e6+10;
char str[N];
int tree[N][26+5];
int idx,n,m;
int cnt[N];

inline void insert(char s[]){
    int p=0;
    for(int i=0;s[i];++i){
        int now=s[i]-'a';
        int &son=tree[p][now];
        if(!son)
            son=++idx;
        p=son;
    }
    cnt[p]++;
}

inline int query(char s[]){
    int res=0,p=0;
    for(int i=0;s[i];++i){
        int now=s[i]-'a';
        int &son=tree[p][now];
        if(son==0)return res;//一旦找到非前缀立即返回

        res+=cnt[son];
        p=son;
    }
    return res;
}

int main(){
    rd(n),rd(m);
    rep(i,1,n){
        scanf("%s",str);
        insert(str);
    }
    rep(i,1,m){
        scanf("%s",str);
        printf("%d\n",query(str));
    }
    return 0;
}

[Breakpoint DP || 01trie] 4260: Codechef REBXOR

Description

imgimg

Input

The first line of input data contains an integer N, the number of elements in the array.

The second line contains N integers A1, A2, ..., AN.

Output

Output to the line containing the maximum possible given expression.

Sample Input

5
1 2 3 1 2

Sample Output

6

HINT

Satisfying the condition (l1, r1, l2, r2) are: (1,2,3,3), (1,2,4,5), (3,3,4,5).

To 100% of the data, 2 ≤ N ≤ 4 * 105,0 ≤ Ai ≤ 109.

Since strict disjoint interval ends, so that the pretreatment and the prefix and suffix exclusive OR and exclusive OR, and then (O (n)) is the maximum seek time

Because it is exclusive or query interval and the maximum, and we can only deal with XOR and the biggest problem is to find two elements in a pile of elements inside;

According to the prefix XOR and nature, if every time we put the prefix XOR and as an element into the trie, then you can guarantee that two elements found XOR and was a range of exclusive-OR and, DP record what prefix exclusive or and and XOR and suffixes. O friends K

const int N=4e5+10;
int n;
int a[N],l[N],r[N];
int tree[N*31][2];
int idx;

inline void insert(int x){
    int p=0;
    dwn(i,30,0){
        int now=x>>i&1;
        int &son=tree[p][now];
        if(!son)son=++idx;
        p=son;
    }
}

inline int query(int x){
    int res=0,p=0;
    dwn(i,30,0){
        int now=x>>i&1;
        if(tree[p][now^1]){
            p=tree[p][now^1];
            res+=1<<i;
        }
        else {
            p=tree[p][now];
        }
    }
    return res;
}

int main(){
    rd(n);
    rep(i,1,n)rd(a[i]);
    int now=0;
    insert(0);
    rep(i,1,n){
        now^=a[i];
        l[i]=max(l[i-1],query(now));
        insert(now);
    }
    mem(tree,0);
    idx=0,now=0;
    dwn(i,n,1){
        now^=a[i];
        r[i]=max(r[i+1],query(now));
        insert(now);
    }
    int ans=0;
    rep(i,1,n-1)
        ans=max(ans,l[i]+r[i+1]);
    printf("%d\n",ans);
//    printf("%.2lf\n",(double)sizeof(tree)/(1<<20));
    return 0;
}

【1A trie 】Shortest Prefixes

After each point, val [son] ++, the current val == 1 quits immediately, and the output of the current string.

Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 24339 Accepted: 10309

Description

A prefix of a string is a substring starting at the beginning of the given string. The prefixes of "carbon" are: "c", "ca", "car", "carb", "carbo", and "carbon". Note that the empty string is not considered a prefix in this problem, but every non-empty string is considered to be a prefix of itself. In everyday language, we tend to abbreviate words by prefixes. For example, "carbohydrate" is commonly abbreviated by "carb". In this problem, given a set of words, you will find for each word the shortest prefix that uniquely identifies the word it represents.

In the sample input below, "carbohydrate" can be abbreviated to "carboh", but it cannot be abbreviated to "carbo" (or anything shorter) because there are other words in the list that begin with "carbo".

An exact match will override a prefix match. For example, the prefix "car" matches the given word "car" exactly. Therefore, it is understood without ambiguity that "car" is an abbreviation for "car" , not for "carriage" or any of the other words in the list that begins with "car".

Input

The input contains at least two, but no more than 1000 lines. Each line contains one word consisting of 1 to 20 lower case letters.

Output

The output contains the same number of lines as the input. Each line of the output contains the word from the corresponding line of the input, followed by one blank space, and the shortest prefix that uniquely (without ambiguity) identifies this word.

Sample Input

carbohydrate
cart
carburetor
caramel
caribou
carbonic
cartilage
carbon
carriage
carton
car
carbonate

Sample Output

carbohydrate carboh
cart cart
carburetor carbu
caramel cara
caribou cari
carbonic carboni
cartilage carti
carbon carbon
carriage carr
carton carto
car car
carbonate carbona
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
const int N=1e3+5,S=20+5;
int tot;
char s[N][S];
int tree[N*S][30],idx=0;
int val[N*S];

inline void insert(char s[]){
    int p=0;
    for(int i=0;s[i];++i){
        int now=s[i]-'a';
        int &son=tree[p][now];
        if(!son)son=++idx;
        val[son]++;
        p=son;
    }
}

inline void query(char s[]){
    int p=0;
    bool flag=0;
    for(int i=0;s[i];++i){
        int now=s[i]-'a';
        int &son=tree[p][now];
        if(val[son]==1){
            rep(j,0,i)
                printf("%c",s[j]);
            flag=1;
            break;
        }
        p=son;
    }
    if(!flag)cout<<s;
}

int main(){
    while(scanf("%s",s[++tot])!=EOF){
        insert(s[tot]);
    }
    tot--;
    rep(i,1,tot){
        printf("%s ",s[i]);
        query(s[i]);
        puts("");
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/sjsjsj-minus-Si/p/11785202.html