zoukankan      html  css  js  c++  java
  • gym102861 C-Concatenating Teams 字符串hash

    gym102861 C-Concatenating Teams

    题意

    给定两个集合(A,B)(A)(B)中分别有(n)(m)个字符串,每个集合中的字符串互不相同,将(A)中的字符串和(B)中的字符串两两按(A)在前(B)在后的顺序拼接,生成(n imes m)个字符串,得到集合(C),一个集合中的一个字符串是独特的当且仅当用它和另一个集合中的所有字符串拼接生成的字符串在(C)中都是唯一的,问(A)(B)中分别有多少个独特的字符串。

    分析

    设字符串三元组((x,x',S))满足(x=x'S),且(x)(x')都属于集合(A),三元组((y,y',T))满足(y=Ty'),且(y)(y')都属于集合(B),能发现当(S=T)时,(x,x',y,y')都不是独特的字符串,那么利用字符串(hash+map),就可以快速解决,具体实现看代码。

    Code

    #include<bits/stdc++.h>
    #define rep(i,x,n) for(int i=x;i<=n;i++)
    #define per(i,n,x) for(int i=n;i>=x;i--)
    #define sz(a) int(a.size())
    #define pii pair<int,int>
    #define ll long long
    #define ull unsigned long long
    #define pb push_back
    #define mp make_pair
    #define se second
    #define fi first
    using namespace std;
    const double eps=1e-8;
    const int mod=1e9+7;
    const int N=1e5+10;
    const int inf=1e9;
    const ull base=131;
    map<ull,int>h1,h2;
    map<ull,bool>v1,v2;
    int n,m,len;
    vector<ull>p,ha;
    string s[N],t[N];
    int a[N],b[N];
    ull get(int l,int r)
    {
        return (ull)ha[r]-ha[l-1]*p[r-l+1];
    }
    void ins(string s)
    {
        len=s.size();
        p.resize(len+1);ha.resize(len+1);
        p[0]=1,ha[0]=0;
        for(int i=1;i<=len;i++)
        {
            p[i]=p[i-1]*base;
            ha[i]=ha[i-1]*base+(ull)s[i-1];
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>n>>m;
        rep(i,1,n) cin>>s[i];
        sort(s+1,s+n+1,[](string x,string y){return sz(x)<sz(y);});
        rep(i,1,m) cin>>t[i];
        sort(t+1,t+m+1,[](string x,string y){return sz(x)<sz(y);});
        rep(i,1,n){
        	ins(s[i]);
    	    h1[ha[len]]=i;
    	    for(int j=1;j<len;j++) if(h1.count(ha[j])){
    	    	 v1[get(j+1,len)]=1;
    	    }
    	}
    	rep(i,1,m){
    		ins(t[i]);
    	    h2[ha[len]]=i;
    	    for(int j=1;j<len;j++) if(h2.count(get(j+1,len))){
    	    	 v2[ha[j]]=1;
    	    }
    	}
        rep(i,1,n){
        	ins(s[i]);
    	    for(int j=1;j<len;j++) if(h1.count(ha[j])&&v2.count(get(j+1,len))){
    	    	 a[i]=a[h1[ha[j]]]=1;
    	    }
        }
        rep(i,1,m){
        	ins(t[i]);
    	    for(int j=1;j<len;j++) if(h2.count(get(j+1,len))&&v1.count(ha[j])){
    	    	 b[i]=b[h2[get(j+1,len)]]=1;
    	    }
        }
        int A=0,B=0;
        rep(i,1,n) A+=(a[i]==0);
        rep(i,1,m) B+=(b[i]==0);
        cout<<A<<' '<<B<<endl;
        return 0;
    }
    
  • 相关阅读:
    HDU 4588 Count The Carries(找规律,模拟)
    HDU 4287 Intelligent IME(string,map,stl,make_pair)
    make_pair() (STL)
    HDU 4022 Bombing(stl,map,multiset,iterater遍历)
    hdu 2094 产生冠军(STL,set)
    zoj 2358,poj 1775 Sum of Factorials(数学题)
    浅谈this在普通函数里情况
    浅谈offset
    常见的一些属性操作
    明天就是七夕情人节了,还在为找对象的事而烦恼吗?单身的点进来看一看了啊,都是干货
  • 原文地址:https://www.cnblogs.com/xyq0220/p/14143605.html
Copyright © 2011-2022 走看看