• Day2T2 分配笔名//CF566A


    首先建一个Trie,考虑贪心选深层节点合并。

    #include<bits/stdc++.h>
    #define fr(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    const int N=2e6+5;
    int n,p=1;
    int ch[N][26],cnt[N][2];
    long long ans;
    inline void insert(char *a,int v){//普通插入
        int u=1;
        fr(i,0,strlen(a)-1){
            int c=a[i]-'a';
            if(!ch[u][c])ch[u][c]=++p;
            u=ch[u][c];
        }
        ++cnt[u][v];//当前节点结尾的单词+1
    }
    inline void dfs(int u,int dep){
        fr(i,0,25){
            if(ch[u][i])dfs(ch[u][i],dep+1);//递归到深层子节点,让能合并的先合并,得到的就是更优解
            cnt[u][0]+=cnt[ch[u][i]][0];//加上子节点剩余的字符串
            cnt[u][1]+=cnt[ch[u][i]][1];
        }
        int k=min(cnt[u][0],cnt[u][1]);//计算公共部分
        ans+=1ll*k*dep;//累计次数
        cnt[u][0]-=k;cnt[u][1]-=k;//消除已匹配的数量
    }
    char a[N];
    int main(){
        scanf("%d",&n);
        fr(i,1,n)cin>>a,insert(a,0);
        fr(i,1,n)cin>>a,insert(a,1);
        dfs(1,0);
        cout<<ans<<endl;
    }

    如果要求输出方案呢?

    即是CF566A

     考虑用一个Vector来维护每个点结尾的ID,也没什么差吧

    #include<vector>
    #pragma GCC optimize("O2")
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("O3")
    #include<cstring>
    #include<iostream>
    #include<cstdio>
    #define fr(i,a,b) for(register int i=a;i<=b;++i)
    #define rf(i,a,b) for(register int i=a;i>=b;--i)
    using namespace std;
    const int N=1e6+5;
    int n,p=1,pa[N];
    int ch[N][26];
    vector<int> cnt[N][2];
    vector<pair<int,int> > as;
    long long ans;
    inline void dfs(int u,int dep){
        fr(i,0,25){
            int v=ch[u][i];
            if(v){
                dfs(v,dep+1);
                for(register int j=0;j<cnt[v][0].size();++j)cnt[u][0].push_back(cnt[v][0][j]);//记录子节点的id
                for(register int j=0;j<cnt[v][1].size();++j)cnt[u][1].push_back(cnt[v][1][j]);
            }
        }
        ans+=min(cnt[u][0].size(),cnt[u][1].size())*dep;//先把共同的匹配
        for(register int i=min(cnt[u][0].size(),cnt[u][1].size())-1;i>-1;--i){
            as.push_back({cnt[u][0][cnt[u][0].size()-1],cnt[u][1][cnt[u][1].size()-1]});//记录方案
            cnt[u][0].pop_back();cnt[u][1].pop_back();//删除已匹配的数
        }
    }
    string a;
    int main(){
        cin>>n;
        fr(id,1,n){
            cin>>a;
            int u=1;
            for(register int i=0;i<a.size();++i){
             int c=a[i]-'a';
             if(ch[u][c]==0)ch[u][c]=++p;
             u=ch[u][c];
            }
            cnt[u][0].push_back(id);
        }
        fr(id,1,n){
            cin>>a;
            int u=1;
            for(int i=0;i<a.size();++i){
             int c=a[i]-'a';
             if(!ch[u][c])ch[u][c]=++p;
             u=ch[u][c];
            }
            cnt[u][1].push_back(id);//记录
        }
        dfs(1,0);
        printf("%d
    ",ans);
        fr(i,0,n-1)printf("%d %d
    ",as[i].first,as[i].second);
    }

    还有,string和char差这么多,快了N倍

  • 相关阅读:
    es字符串字段类型的私有属性 建立索引的分析器 用于查询的分析器 短语查询优化
    限制索引、字段的自动创建 无模式与自定义 索引结构映射 切面搜索
    Lucene索引数计算
    API网关性能比较:NGINX vs. ZUUL vs. Spring Cloud Gateway vs. Linkerd API 网关出现的原因
    git 中 A C D M R T U X 分别解释
    通过 ulimit 改善系统性能
    机器重启 查看crontab执行历史记录crontab没有执行
    烂代码 git blame
    es 中 for in for of
    发散阶段 收集阶段 标识符 得分 副本角色
  • 原文地址:https://www.cnblogs.com/coder-cjh/p/11628425.html
Copyright © 2020-2023  润新知