• Fzu2267 The Bigger the Better


    题意:两个字符串,每次选一个字符串,删掉该字符,重复上述操作直到删除,最后问最小删除的最小字典序是多少

    题解:每次对比字符,选择最小的字符来删,如果有相等的字符,那么就要看当前的后缀,选择字典序最小的那个后缀,后缀的字典序可以用后缀数组来搞

    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #define maxn 200100
    using namespace std;
    struct SuffixArray {
        int s[maxn];
        int sa[maxn],ra[maxn],height[maxn],t1[maxn],t2[maxn],c[maxn],n;
        void build_sa(int m) {
            int i,*x=t1,*y=t2;
            for(i=0; i<m; i++) c[i]=0;
            for(i=0; i<n; i++) c[x[i]=s[i]]++;
            for(i=1; i<m; i++) c[i]+=c[i-1];
            for(i=n-1; i>=0; i--) sa[--c[x[i]]]=i;
            for(int k=1; k<=n; k<<=1) {
                int p=0;
                for(i=n-k; i<n; i++) y[p++]=i;
                for(i=0; i<n; i++)if(sa[i]>=k) y[p++]=sa[i]-k;
                for(i=0; i<m; i++) c[i]=0;
                for(i=0; i<n; i++) c[x[y[i]]]++;
                for(i=1; i<m; i++) c[i]+=c[i-1];
                for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i];
                swap(x,y);
                p=1,x[sa[0]]=0;
                for(i=1; i<n; i++)
                    x[sa[i]]= y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]? p-1:p++;
                if(p>=n) break;
                m=p;
            }
        }
        void build_height() {
            int i,j,k=0;
            for(i=0; i<n; i++)ra[sa[i]]=i;
            for(i=0; i<n; i++) {
                if(k)k--;
                j=sa[ra[i]-1];
                while(s[i+k]==s[j+k])k++;
                height[ra[i]]=k;
            }
        }
    }sa;
    int main(){
        int T, n, m, ca = 1;
        ios::sync_with_stdio(0);
        cin>>T;
        while(T--){
            //memset(sa.s, 0, sizeof(sa.s));
            cin>>n>>m;
            for(int i=0;i<n;i++) cin>>sa.s[i];
            sa.s[n] = sa.s[n+m+1] = 0;
            for(int i=n+1;i<n+m+1;i++) cin>>sa.s[i];
            sa.n = n+m+2;
            sa.build_sa(15);
            sa.build_height();
            int p1 = 0, p2 = n+1, num = 0;
            cout<<"Case "<<ca++<<": ";
            while(p1<n&&p2<n+m+1){
                if(sa.ra[p1] > sa.ra[p2]) cout<<sa.s[p1++];
                else cout<<sa.s[p2++];
            }
            while(p1<n) cout<<sa.s[p1++];
            while(p2<n+m+1) cout<<sa.s[p2++];
            cout<<endl;
        }
        return 0;
    }
    /*
    10
    9 9
    1 2 3 4 5 6 7 8 9
    2 3 1 4 6 5 7 9 8
    
    10
    1 1
    9
    9
    
    10
    9 9
    1 2 3 4 5 6 7 8 9
    2 3 1 4 6 5 7 9 8
    */
  • 相关阅读:
    Servlet 生命周期、工作原理(转)
    JVM的内存区域划分(转)
    Java的四个基本特性和对多态的理解
    单例模式和多例模式的区别(转)
    TCP/IP协议体系结构简介
    数据库优化性能
    存储过程的优缺点(转)
    ConurrentHashMap和Hashtable的区别
    XML和JSON优缺点
    HashMap和HashTable的区别
  • 原文地址:https://www.cnblogs.com/Noevon/p/9002890.html
Copyright © 2020-2023  润新知