zoukankan      html  css  js  c++  java
  • 19上海icpc网络赛 G Substring哈希好题

    这道题乍一看不能hash实际上最多sqrt(1e5)种长度,所以1e4*sqrt(1e5)就可以了
    但这种hash第一次见

    #include <bits/stdc++.h>
    using namespace std;
    #define ull unsigned long long
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define IO ios::sync_with_stdio(false);cin.tie(0)
    const int maxn = 2e4+5;
    const int maxm = 1e5+5;
    const int seed = 131;
    
    unordered_map<ull,int>mp[26][26];
    unordered_map<ull,bool>vis[26][26];
    string z,s;
    int ans[maxn],n;
    ull p[30];
    struct Q{
        int id,len,l,r;
        ull has;
    }q[maxn];
    bool cmp(Q a,Q b){
        return a.len<b.len;
    }
    
    void getans(int x){
        if(x>n) return;
        int l = 0,r = 0;
        ull res = 0;
        while(r<x) res+=p[s[r]-'a'],r++;
        if(vis[s[l]-'a'][s[r-1]-'a'].count(res)) mp[s[l]-'a'][s[r-1]-'a'][res]++;
        while(r<n){
            res-=p[s[l]-'a'],l++,res+=p[s[r]-'a'];
            if(vis[s[l]-'a'][s[r]-'a'].count(res)) mp[s[l]-'a'][s[r]-'a'][res]++;
            r++;
        }
    }
    
    void init(){
        forn(i,26) forn(j,26) mp[i][j].clear(),vis[i][j].clear();
    }
    
    int main(){
    	IO;
    	p[0] = 1;
    	for1(i,26) p[i] = p[i-1]*seed;
    	int t;cin>>t;
    	while(t--){
    		cin>>s;
            init();
            n = s.size();
    		int m;cin>>m;
    		for1(i,m) {
                cin>>z;
                int len = z.size();
                q[i].len = len;
                q[i].id = i;
                q[i].l = z[0]-'a';
                q[i].r = z[len-1]-'a';
                q[i].has = 0;
                forn(j,len) {
                    q[i].has+=p[z[j]-'a'];
                    //cerr<<z[j]-'a'<<' '<<p[z[j]-'a']<<"@!#"<<'
    ';
                }
                //cerr<<len<<' '<<p[0]<<' '<<q[i].has<<'
    ';
                vis[q[i].l][q[i].r][q[i].has] = true;
            }
            sort(q+1,q+m+1,cmp);
            for1(i,m){
               // cerr<<q[i].l<<' '<<q[i].r<<' '<<q[i].has<<'
    ';
                if(q[i].len!=q[i-1].len) getans(q[i].len);
                ans[q[i].id] = mp[q[i].l][q[i].r][q[i].has];
            }
            for1(i,m) cout<<ans[i]<<'
    ';
    	}
    	return 0;
    }
    
  • 相关阅读:
    洛谷P1865 A%B Problem
    树状数组的操作
    树状数组的基础知识
    卡常优化中最为奇怪的操作
    inline的用法
    快速读入的方法
    P1059 明明的随机数及unique去重的用法
    P3376 网络最大流 【模板】
    Gym
    HDU
  • 原文地址:https://www.cnblogs.com/AlexPanda/p/12520296.html
Copyright © 2011-2022 走看看