• hdu6096 String


    String 
    Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) 

    Problem Description 
    Bob has a dictionary with N words in it. 
    Now there is a list of words in which the middle part of the word has continuous letters disappeared. The middle part does not include the first and last character. 
    We only know the prefix and suffix of each word, and the number of characters missing is uncertain, it could be 0. But the prefix and suffix of each word can not overlap. 
    For each word in the list, Bob wants to determine which word is in the dictionary by prefix and suffix. 
    There are probably many answers. You just have to figure out how many words may be the answer.

    Input 
    The first line of the input gives the number of test cases T; T test cases follow. 
    Each test case contains two integer N and Q, The number of words in the dictionary, and the number of words in the list. 
    Next N line, each line has a string Wi, represents the ith word in the dictionary (0<|Wi|≤100000) 
    Next Q line, each line has two string Pi , Si, represents the prefix and suffix of the ith word in the list (0<|Pi|,|Si|≤100000,0<|Pi|+|Si|≤100000) 
    All of the above characters are lowercase letters. 
    The dictionary does not contain the same words.

    Limits 
    T≤5 
    0< N,Q≤100000 
    ∑Si+Pi≤500000 
    ∑Wi≤500000

    Output 
    For each test case, output Q lines, an integer per line, represents the answer to each word in the list.

    Sample Input 

    4 4 
    aba 
    cde 
    acdefa 
    cdef 
    a a 
    cd ef 
    ac a 
    ce f

    Sample Output 



    分析:比赛时未做出,还是太菜。。

       事实证明只要不是太暴力都能过吧,大概。。

       按题解说,前缀和后缀分别按字典序排序,然后对询问二分到端点所在区间;

       这样问题转化为了扫描线,可以用数据结构离线查询;

       然后因为有重叠,所以枚举重叠长度哈希即可;

       用了string,map,发现其实评测机还是很快的,orz;

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <bitset>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cassert>
    #include <ctime>
    #define rep(i,m,n) for(i=m;i<=(int)n;i++)
    #define mod 998244353
    #define inf 0x3f3f3f3f
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define sys system("pause")
    #define ls rt<<1
    #define rs rt<<1|1
    #define all(x) x.begin(),x.end()
    const int maxn=1e5+10;
    const int N=5e5+10;
    using namespace std;
    ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    ll qmul(ll p,ll q,ll mo){ll f=0;while(q){if(q&1)f=(f+p)%mo;p=(p+p)%mo;q>>=1;}return f;}
    ll qpow(ll p,ll q,ll mo){ll f=1;while(q){if(q&1)f=f*p%mo;p=p*p%mo;q>>=1;}return f;}
    int n,m,k,t,ret[maxn],dq[maxn],td1[maxn],td2[maxn],id1[maxn],id2[maxn];
    map<unsigned ll,int>pq;
    unsigned ll h[2][maxn],xp[maxn];
    string a[maxn],b[maxn],c,d;
    void init()
    {
        xp[0]=1;
        for(int i=1;i<=maxn-10;i++)xp[i]=xp[i-1]*123;
    }
    void ha(string p)
    {
        unsigned ll now=0;
        int len=p.length();
        for(int i=len-1;i>=0;i--)now=now*123+p[i];
        pq[now]=1;
    }
    void ha(string p,int tp,int len)
    {
        h[tp][len]=0;
        for(int i=len-1;i>=0;i--)h[tp][i]=h[tp][i+1]*123+p[i];
    }
    bool cmp1(int x,int y){return a[x]<a[y];}
    bool cmp2(int x,int y){return b[x]<b[y];}
    void add(int x,int y)
    {
        while(x<=n)dq[x]+=y,x+=x&(-x);
    }
    int get(int x)
    {
        int ret=0;
        while(x)ret+=dq[x],x-=x&(-x);
        return ret;
    }
    vi qu[maxn],pos[maxn];
    struct node
    {
        int x,y,z,w;
    }q[maxn];
    int main()
    {
        int i,j;
        init();
        scanf("%d",&t);
        while(t--)
        {
            pq.clear();
            scanf("%d%d",&n,&m);
            rep(i,1,n)
            {
                cin>>a[i];
                b[i]=a[i];
                reverse(b[i].begin(),b[i].end());
                ha(a[i]);
                id1[i]=id2[i]=i;
                dq[i]=0;
            }
            sort(id1+1,id1+n+1,cmp1);
            sort(id2+1,id2+n+1,cmp2);
            sort(a+1,a+n+1);
            sort(b+1,b+n+1);
            rep(i,1,n)td1[id1[i]]=i,td2[id2[i]]=i;
            rep(i,1,n)pos[td1[i]].pb(td2[i]);
            rep(i,1,m)
            {
                ret[i]=0;
                cin>>c>>d;
                int len1=c.length(),len2=d.length();
                ha(c,0,len1);
                ha(d,1,len2);
                int l=len1-1,r=0;
                while(l>=0&&r<len2)
                {
                    if(h[0][l]-h[0][len1]*xp[len1-l]==h[1][0]-h[1][r+1]*xp[r+1])
                    {
                        unsigned ll tmp=h[0][0]-h[0][l]*xp[l]+h[1][0]*xp[l];
                        if(pq.count(tmp))ret[i]--;
                    }
                    --l,++r;
                }
                reverse(d.begin(),d.end());
                int pos1=0,pos2=0,pos3=0,pos4=0;
                l=1,r=n;
                while(l<=r)
                {
                    int mid=l+r>>1;
                    if(a[mid]>=c)pos1=mid,r=mid-1;
                    else l=mid+1;
                }
                if(pos1&&a[pos1].substr(0,len1)!=c)pos1=0;
                l=1,r=n;
                while(l<=r)
                {
                    int mid=l+r>>1;
                    if(a[mid]<=c||a[mid].substr(0,len1)==c)pos2=mid,l=mid+1;
                    else r=mid-1;
                }
                l=1,r=n;
                while(l<=r)
                {
                    int mid=l+r>>1;
                    if(b[mid]>=d)pos3=mid,r=mid-1;
                    else l=mid+1;
                }
                if(pos3&&b[pos3].substr(0,len2)!=d)pos3=0;
                l=1,r=n;
                while(l<=r)
                {
                    int mid=l+r>>1;
                    if(b[mid]<=d||b[mid].substr(0,len2)==d)pos4=mid,l=mid+1;
                    else r=mid-1;
                }
                if(pos1&&pos3)
                {
                    q[i]=node{pos1,pos3,pos2,pos4};
                    qu[pos1-1].pb(-i),qu[pos2].pb(i);
                }
            }
            rep(i,1,n)
            {
                rep(j,0,pos[i].size()-1)add(pos[i][j],1);
                rep(j,0,qu[i].size()-1)
                {
                    int x=qu[i][j];
                    if(x<0)
                    {
                        x=-x;
                        ret[x]-=get(q[x].w)-get(q[x].y-1);
                    }
                    else ret[x]+=get(q[x].w)-get(q[x].y-1);
                }
            }
            rep(i,1,m)printf("%d
    ",ret[i]);
            rep(i,1,n)qu[i].clear(),pos[i].clear();
        }
        return 0;
    }
  • 相关阅读:
    常用的DOCS命令
    [51NOD1126]求递推序列的第n项(矩阵快速幂)
    [HDOJ2830]Matrix Swapping II(胡搞)
    [每天一道A+B]签到检测程序
    [HIHO1260]String Problem I(trie树)
    [HIHO1300]展胜地的鲤鱼旗(栈,dp)
    [HIHO1299]打折机票(线段树)
    [51NOD1087]1 10 100 1000(规律,二分)
    [POJ2002]Squares(计算几何,二分)
    [HDOJ1015]Safecracker(DFS, 组合数学)
  • 原文地址:https://www.cnblogs.com/dyzll/p/7342432.html
Copyright © 2020-2023  润新知