• Codeforces-963 D Frequency of String


    题意:给你一个字符串,进行q次询问操作,每次给你一个n和一个子串,问能否在字符串中出现n次子串,若可以输出最短长度的n次子串,否则输出-1

    题解:优雅的暴力哈希,枚举每一个不同种长度的子串,注意是不同种!因为这样子能减少枚举的次数,这是一个巨大的优化,同时用unordered_map这个不按key排序的map,减少logn的STL复杂度。(我就说一定存在不按照key排序的map啊啊啊)

    还是我很挫的代码

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <map>
    #include <unordered_map>
    #include <queue>
    #include <vector>
    #include <cstring>
    #include <iomanip>
    #include <set>
    #include<ctime>
    //CLOCKS_PER_SEC
    #define se second
    #define fi first
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define Pii pair<int,int>
    #define Pli pair<ll,int>
    #define ull unsigned long long
    #define pb push_back
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    const int N=1e5+5;
    const ull base=131;
    const int INF=0x3f3f3f3f;
    using namespace std;
    ull Hash[N];
    ull p[N];
    unordered_map<ull,int>mp;
    ull get(int l,int r){
        if(l==0)return Hash[r];
        return Hash[r]-Hash[l-1]*p[r-l+1];
    }
    int L[N],id[N],a[N];
    ull H[N];
    bool cmp(int x,int y){
        return L[x]<L[y];
    }
    vector<int>ans[N];
    int main(){
        fio;
        string str;
        cin>>str;
        int len=str.length();
        Hash[0]=str[0];
        p[0]=1;
        for(int i=1;i<len;i++){
            Hash[i]=Hash[i-1]*base+str[i];
            p[i]=p[i-1]*base;
        }
        int n;
        cin>>n;
        for(int i=1;i<=n;i++){
            string op;
            cin>>a[i];
            cin>>op;
            id[i]=i,L[i]=op.length();
            ull u=0;
            for(int j=0;j<L[i];j++){
                u=u*base+op[j];
            }
            H[i]=u;
            mp[H[i]]=i;
        }
        sort(id+1,id+1+n,cmp);
        for(int i=1,oo=1;i<=n;i+=oo){
            oo=1;
            while(L[id[oo+i]]==L[id[i]])oo++;
            int pp=id[i];
            for(int j=0;j+L[pp]<=len;j++){
                ull m=get(j,j+L[pp]-1);
                if(mp.find(m)!=mp.end()){
                    ans[mp[m]].pb(j);
                }
            }
        }
        for(int i=1;i<=n;i++){
            if(ans[i].size()<a[i])cout<<-1<<endl;
            else{
                int MIN=INF;
                for(int j=a[i]-1;j<ans[i].size();j++){
                    MIN=min(MIN,ans[i][j]-ans[i][j-a[i]+1]+L[i]);
                }
                cout<<MIN<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    JS编码解码详解
    web的几种返回顶部
    图片的懒加载的两种效果
    获取两个日期差
    C#虚方法
    依赖注入(DI)和Ninject
    在应用程序级别之外使用注册为 allowDefinition='MachineToApplication' 的节是错误的
    PetShop的系统架构设计
    C#综合揭秘——细说多线程(下)
    C# Socket编程(4)初识Socket和数据流
  • 原文地址:https://www.cnblogs.com/Mrleon/p/8886982.html
Copyright © 2020-2023  润新知