zoukankan      html  css  js  c++  java
  • [UVa 11732] "strcmp()"Anyone?

    Link:

    UVa 11732 传送门

    Solution:

    思路还是很套路:建$Trie$树,在$Trie$树上跑一遍统计答案

    (统计答案时注意将叶节点特殊处理,同时对于$e(u,v)$用$val[v]*(val[u]-val[v])$来统计个数)

    重点在于此题的存储方式:左儿子右兄弟存储法 (链表式存储法)

    由于此题节点数$MAXN=4e6$,如果按照$ch[MAXN][27]$建图刚好$MLE$

    而链表式存储法优点就在于省空间,不用建立多余的节点,只不过牺牲了查询的效率

    实现起来很像链式前向星:$ls[i]$相当于$head[i]$,$rb[i]$相当于$nxt[i]$,每次插入也是从头部插入

    Tip:在处理过程中将数据初始化,尽量不用$memset$

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int MAXN=4e6+10;
    char s[1005],ch[MAXN];ll res=0;
    int T,n,ls[MAXN],rb[MAXN],val[MAXN],cnt=0;
    
    void insert()
    {
        int len=strlen(s);
        int u=0,v;val[0]++;
        for(int i=0;i<=len;i++)
        {
            bool f=false;
            for(v=ls[u];v;v=rb[v])
                if(ch[v]==s[i]){f=true;break;}
            
            if(!f)
            {
                v=++cnt;ch[v]=s[i]; //建立新节点
                rb[v]=ls[u];ls[u]=v;
                ls[v]=0;val[v]=0;
            }
            u=v;val[u]++;
        }
    }
    
    void dfs(int dep,int u)
    {
        if(!ls[u]){res+=1ll*val[u]*(val[u]-1)*dep;return;} //统计叶节点的答案
        
        ll sum=0;int v;
        for(v=ls[u];v;v=rb[v]) //统计答案
            sum+=val[v]*(val[u]-val[v]);
        res+=1ll*sum/2*(2*dep+1);
        
        for(v=ls[u];v;v=rb[v])
            dfs(dep+1,v);
    }
    
    int main()
    {
        while(scanf("%d",&n)==1 && n)
        {
            cnt=0;val[0]=ls[0]=rb[0]=0;
            for(int i=1;i<=n;i++)
                scanf("%s",s),insert();
            
            res=0;dfs(0,0);
            printf("Case %d: %lld
    ",++T,res);
        }
        return 0;
    }
  • 相关阅读:
    ping命令
    第一次手写Loadrunner测试脚本
    select into from和insert into select
    网络安全领域常说的payload
    如何查看LoadRunner日志
    验证码测试
    HTTP的请求和响应
    LoadRunner能录制微信登录过程么?
    切面编程AOP之KingAOP
    编程规范
  • 原文地址:https://www.cnblogs.com/newera/p/9248527.html
Copyright © 2011-2022 走看看