zoukankan      html  css  js  c++  java
  • [Nowcoder] Browser Games-2021牛客多校10-A | Hash /压缩Trie

    本题哈希做法参考博客:链接

    Description

    In the upcoming n n n days, n n n browser games will be released on a new website. According to the plan, the administrator will release a new game per day. Users have to open the corresponding URL (Uniform Resource Locator) and get feedback from the server to download a game.

    However, the setup of the server uses unreadable legacy codes. Once a user somehow finds the URL of an unreleased game, the data of the game would leak out. To temporarily fix the problem, the administrator decided to add a series of confirmation prefixes, which are non-empty strings, at the server-side. The server will respond with the correct game data when the requested URL does correspond to a game (no matter released or unreleased) and at least one confirmation prefix is a prefix of the URL; otherwise, the server will declare that the game is not found.

    To make the work easier, the administrator asks you to find the minimum number of confirmation prefixes the server required to avoid data leaks every time after a new game release.

    Input

    The first line contains an integer n (1≤n≤5×104), indicating the number of browser games to be released.

    In the next n lines, the i-th line contains a non-empty string, consisting of only lowercase letters (‘a’ to ‘z’), dots (‘.’) and forward slashes (‘/’), indicating the URL of the browser game released on the i-th day.

    It is guaranteed that the length of each given URL is at most 50, and no given URL is the prefix of any other given URL.

    Output

    Output n lines, the i-th of which contains an integer indicating the minimum number of required confirmation prefixes after the i-th new game released.

    Input Copy

    3
    ufoipv.ofu
    hsbocmvfgboubtz.kq
    hfotijo.njipzp.dpn/kb
    

    Output

    1
    2
    2
    

    给出 n 个字符串,对于每个 i ,找到最少需要多少个前缀,将第 1 -> i 个字符串的前缀包含在内,不包含第 i + 1 -> n 个字符串的前缀

    首先暴力的字典树解法(由于内存的加强,并不能通过该题)
    压缩Trie 是可以的

    const int maxn = 2600007;
    const int N = 5e4 + 7;
    int n, rt, idx, ans;
    int tree[maxn][30];
    char s[maxn][60];
    int last[maxn];
    ll pre[maxn];
    int getId(char c) {
        if(c == '.')
            return 1;
        else if(c == '/')
            return 2;
        else
            return (int)(c - 'a' + 3);
    }
    void Insert(char ss[], int id) {
        rt = 0;
        int len = strlen(ss);
        for(int i=0;i<len;i++){
            int x = getId(ss[i]);
            if(!tree[rt][x]) tree[rt][x] = ++ idx;
            last[tree[rt][x]] = id;
            rt = tree[rt][x];
        }
    }
    void Update(char ss[], int id) {
        int x = 0, pre_pos = 0, rt = 0;
        int len = strlen(ss);
        for(int i = 0; i < len; i++) {
            x = getId(ss[i]);
            int pos = last[tree[rt][x]];
            if(pos == id) {
                if(i == 0) {
                    pre[id] ++;
                    return;
                } else {
                    pre[id] ++;
                    pre[pre_pos] --;
                    return;
                }
            }
            rt = tree[rt][x];
            pre_pos = pos;
        }
    }
    int main() {
        n = read, idx = 0;
        for(int i = 1; i <= n; i++) {
            scanf("%s", s[i]);
            Insert(s[i], i);
        }
        for(int i = 1; i <= n; i++)
            Update(s[i], i);
        ans = 0;
        for(int i = 1; i <= n; i++) {
            ans += pre[i];
            printf("%d
    ", ans);
        }
        return 0;
    }
    /**
    
    
    **/
    

    哈希做法:

    #define ull unsigned long long
    struct Hash {
        static const ull md1 = 1e9 + 7, md2 = 1e9 + 9;
        ull has1, has2;
        /// Hash() {}
        Hash(ull h1=0, ull h2=0): has1(h1), has2(h2) {}
        Hash operator+(const Hash& p) const {
            return Hash((has1 + p.has1) % md1, (has2 + p.has2) % md2);
        }
        Hash operator*(const Hash& p) const {
            return Hash((has1 * p.has1) % md1, (has2 * p.has2) % md2);
        }
        ull getVal() {
            return has1 * md2  + has2;
        }
    } Has[maxn], base(233, 2333);
    unordered_map<ll, vector<int> > mp;
    char s[maxn][117];
    int pos[maxn], ans[maxn];
    int main() {
        int n = read;
        for(int i = 1; i <= n; i++) {
            scanf("%s", s[i]);
            Has[i] = Hash(s[i][0], s[i][0]);
            mp[Has[i].getVal()].push_back(i);
            pos[i] = 0;
        }
        for(int i = n; i >= 1; i--) {
            ans[i] = mp.size();
            int len = strlen(s[i]);
            Hash temp;
            for(int j = 0; j < len; j++) {
                temp = temp * base + Hash(s[i][j], s[i][j]);
                auto at = mp.find(temp.getVal());
                if(at != mp.end()) {
                    for(int k : at->second) {
                        if(k != i) {
                            pos[k] ++;
                            Has[k] = Has[k] * base + Hash(s[k][pos[k]], s[k][pos[k]]);
                            mp[Has[k].getVal()].push_back(k);
                        }
                    }
                    mp.erase(at);
                }
            }
        }
        for(int i = 1; i <= n; i++)
            printf("%d
    ", ans[i]);
        return 0;
    }
    /**
    
    
    **/
    

    标称做法:

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 100005
    #define maxm 105
    int sum[maxn];
    char s[maxn][maxm];
    int n;
    int date[maxn];
    bool cmp(int a,int b) {
    	return strcmp(s[a]+1,s[b]+1)<0;
    }
    void solve(int l,int r,int end,int k) {
    	int nzk=0;
    	if(l==r)return;
    	for(int i=l,last=l; i<=r; i++) {
    		nzk=max(nzk,date[i]);
    		if(i==r||s[date[i]][k]!=s[date[i+1]][k]) {
    			sum[nzk]++;
    			sum[end]--;
    			solve(last,i,nzk,k+1);
    			last=i+1,nzk=0;
    		}
    	}
    }
    int main() {
    	scanf("%d",&n);
    	for(int i=1; i<=n; i++)
    		scanf("%s",s[i]+1),date[i]=i;
    	sort(date+1,date+1+n,cmp);
    	solve(1,n+1,n+1,1);
    	for(int i=2; i<=n; i++)
    		sum[i]+=sum[i-1];
    	for(int i=1; i<=n; i++)
    		printf("%d
    ",sum[i]);
    }
    
  • 相关阅读:
    GridView小知识1
    ASP 中 GridView 的粗浅入门
    SQL连接
    Microsoft Visual Studio 2010 Express for Windows Phone 新建文件 设置启动
    转载一个应届计算机毕业生2012求职之路
    百度之星平衡负载(3.23)
    查找字符串中首个非重复字符
    CreateMutex函数
    关于“Visual Studio 遇到了异常,可能是由于某个扩展导致的”的解决
    无法打开预编译头文件:“Debug\****.pch”: No such file or directory 的解决办法
  • 原文地址:https://www.cnblogs.com/PushyTao/p/15459806.html
Copyright © 2011-2022 走看看