zoukankan      html  css  js  c++  java
  • 『一本通』Trie字典树

    Phone List

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+5;
    int T,n,tot,c[N][10];
    char s[10];
    bool ans,bo[N];
    
    void clear() {
        tot=0,ans=0;
        memset(c,0,sizeof(c));
        memset(bo,false,sizeof(bo));
    }
    bool insert() {
        int len=strlen(s+1),u=0;
        bool flag=0;    
        for(int i=1;i<=len;i++) {
            int v=s[i]-'0';
            if(!c[u][v]) c[u][v]=++tot;
            else if(i==len) flag=1; //没有插入任何新节点 
            u=c[u][v];    
            if(bo[u]) flag=1;
        }    
        bo[u]=1;
        return flag;
    }
    
    int main() {
        scanf("%d",&T);
        while(T--) {
            clear();
            scanf("%d",&n);
            for(int i=1;i<=n;i++) {
                scanf("%s",s+1);
                if(insert()) ans=1; 
            }
            printf("%s
    ",ans?"NO":"YES");
        }
    }

    The XOR Largest Pair

    将$A[i]$看作长度为$32$的二进制$01$串,插入$Trie$字典树。

    对于$A[i]$对应的$32$位二进制串,我们从高位到低位,尽量沿着“与$A[i]$当前位相反的字符指针”向下访问。

    根据$xor$运算“相同得0,不同得1”的性质,即可找出与$A[i]$做$xor$运算结果最大的$A[j]$。

    #include<bits/stdc++.h>
    using namespace std;
    const int O=1e5*30;
    int n,x,tot,ans,c[O][2];
    
    void insert(int x) {
        int u=0;
        for(int i=30;i>=0;i--) {
            int v=(x>>i)&1;
            if(!c[u][v]) c[u][v]=++tot;
            u=c[u][v];
        }
    }
    int cal(int x) {
        int u=0,res=0;
        for(int i=30;i>=0;i--) {
            int v=(x>>i)&1;
            if(c[u][v^1]) res+=1<<i,u=c[u][v^1];
            else u=c[u][v]; 
        }
        return res;
    }
    
    int main() {
        scanf("%d",&n);
        while(n--) {
            scanf("%d",&x);
            ans=max(ans,cal(x));
            insert(x);
        }
        printf("%d",ans);
    }

    背单词

    将所有字符串倒着插入字典树,使后缀变为前缀。

    贪心:不能出现情况1。如果$s1$为$s$的后缀,那么$s1$的序号必须小于$s$的序号。

    要使结点的序号减去其儿子的序号最小,我们从小到大遍历每个结点的子树即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=510000+5;
    int n,tot,cnt,w[N],fro[N],siz[N],fa[N],c[N][26];
    long long ans;
    bool bo[N];
    char s[N];
    struct edge{int to,nxt;}a[N];
    vector<int>vi[N];
    
    void add(int x,int y) {
        a[++cnt].to=y,a[cnt].nxt=fro[x]; fro[x]=cnt;
    }
    void insert(int x) {
        int len=strlen(s+1),u=0;
        for(int i=len;i>0;i--) {
            int v=s[i]-'a';
            if(!c[u][v]) c[u][v]=++tot,fa[tot]=u;
            u=c[u][v];
        }
        bo[u]=1,w[x]=u;
    }
    
    void dfs(int u) {
        siz[u]=1;
        for(int i=fro[u];i;i=a[i].nxt) {
            int v=a[i].to;
            dfs(v);
            siz[u]+=siz[v];
            vi[u].push_back(siz[v]);
        }
        sort(vi[u].begin(),vi[u].end());
        int num=0;
        for(int i=0;i<vi[u].size();i++)
         ans+=num+1,num+=vi[u][i];
    }
    
    int main() {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            scanf("%s",s+1);
            insert(i);
        }
        for(int i=1;i<=n;i++) {
            int k=fa[w[i]];
            while(k&&!bo[k]) k=fa[k];
            add(k,w[i]);
        }
        dfs(0);
        printf("%lld",ans);
    }
  • 相关阅读:
    Evensgn 的债务
    Passward
    拯救莫莉斯
    文艺平衡树
    Fliptile 翻格子游戏
    Making the Grade (bzoj1592)
    紧急疏散evacuate
    Password
    [NOIP2015]斗地主
    运输问题1
  • 原文地址:https://www.cnblogs.com/qq8260573/p/10383391.html
Copyright © 2011-2022 走看看