hdu 4821

来源:互联网 发布:3d动画软件 编辑:程序博客网 时间:2024/06/06 04:10

题意:就是有一个字符串S,要求找到符合以下几种情况S的子串的个数.

情况1: 该子串的长度为L*M

请况2: 该子串的字串被分为M个,在该M个子子串中不存在相同.

(子串不同:出发的下标不同)

解题思路:

对于该问题的核心有两点:因为总串的长度比较大,所以判段字符串时否出现相同,不可能用平常的比较方法,第二如何判断两个相同的字符串到底在那个子串中。

对于第一点,我们可以用字符串hash函数来解决。

对于第二点,我们先算出下标[0,L)的所有子串的请况,那么[L,|s|- L*M]的请况可以根据之前算过的来推出。


#include <stdio.h>#include <string.h>#include <stdlib.h>#include <string>#include <vector>#include <map>#include <math.h>using namespace std;#define MAXSZ 100010#define MOD 100003typedef unsigned int ul;typedef struct node{    node(){            }    node(ul hanum){        //s = key;        hashnum = hanum;    }   // string s;    ul hashnum;};bool vis0[MAXSZ],vis1[MAXSZ];char str[MAXSZ];int hasharr[MAXSZ],cnt,indexs[MAXSZ];int M,L;node vt[MAXSZ];vector<int>vt1[MAXSZ];map<int,int>mp[MAXSZ];//inline ul BKDRHash(char *str){//    ul seed = 31; // 31 131 1313 13131  etc..//    ul hash = 0;////    while (*str)//    {//        hash = hash * seed + (*str++);//    }////    return (hash & 0x7FFFFFFF);//}void init(){    cnt = 0;    //memset(ff,0,sizeof(ff));    //memset(vis2,0,sizeof(vis2));    for(int i=0;i<MAXSZ;++i){        if(mp[i].size()){            mp[i].clear();        }    }}int  hashit(char *key,ul hashnum){    int ind = hashnum%MOD;    while(vis0[ind]){        if(vt[ind].hashnum!=hashnum){            ind++;        }//        else if(vt[ind].s!=key){//            ind++;//        }        else            break;        if(ind==M){           ind%=M;        }    }    if(!vis0[ind]){        //vt[ind].s = key;        vt[ind].hashnum = hashnum;        vis0[ind] = true;        hasharr[cnt++] = ind;    }    return ind;}void prepro(){    char *p0 = str;    char *p1 = str;    char cc;    ul hash = 0;    ul seed = 31;    ul hashnum;    ul tmphs0;    int ind = 0,ind1 = 0;    tmphs0 = 1;    for(;ind<L;++ind){        hash = hash*seed +(*p1++);        //hash %= MOD;        if(ind){            tmphs0 = (tmphs0*seed);        }    }    hashnum = hash&0x7FFFFFFF;    //cc = (*p1);    //(*p1) = 0;    //ind = hashit(p0,hashnum);    //(*p1) = cc;    //vt1[ind].push_back(0);    indexs[0] = hashnum;    while(*p1){        hash = ((hash - tmphs0*(*p0++)));        hash = (hash*seed +(*p1++));        cc = (*p1);        ++ind1;       // (*p1) = 0;       // ind = hashit(p0,hash&0x7FFFFFFF);        //(*p1) = cc;        //vt1[ind].push_back(ind1);        indexs[ind1] = hash&0x7FFFFFFF;    }    }int solve(){   // memset(vis1,false,sizeof(vis1));   // memset(vis2,false,sizeof(vis2));    int len = (int)strlen(str);    int ans ;    int sz;    int tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6;    int up = len - (L*M);    ans = 0;//    for(int i=0;i<cnt;++i){//        tmp0 = hasharr[i];//        sz = (int)vt1[tmp0].size();//        for(int j=0;j<sz;++j){//            for(int k=j+1;k<sz;++k){//                tmp3 = vt1[tmp0][j];//                tmp4 = vt1[tmp0][k];//                tmp1 = (tmp4 - tmp3);//                if(tmp1%L==0){//                    tmp2 = tmp1/L;//                    if(tmp2+1<=M){//                        for(int h=0;h<=up;++h){//                            if(h>tmp3)break;//                            if((tmp3-h)%L==0&&(tmp4-h)%L==0){//                                //tmp5 = (tmp3-h)/L+1;//                                //tmp6 = (tmp4 - h)/L+1;//                                //                                if(!vis1[h]){//                                    vis1[h] = true;//                                    --ans;//                                }//                            }//                        }//                    }//                }//            }//        }//    }        for(int i=0;i<L&&i<=up;++i){     //int ss = 0;        for(int k=i,j=0;j<M;++j,k+=L){            tmp0 = indexs[k];            if(mp[i].count(tmp0)){                //++vis2[tmp0];                ++mp[i][tmp0];                //--ans;                //break;            }            else {               // ++ans;               // ff[ss++] = tmp0;                //++ff[i];                //++vis2[tmp0] ;                mp[i].insert(pair<int,int>(tmp0,1));            }        }        if(mp[i].size()==M){            ++ans;        }    }    int ML = (M-1)*L;    for(int i=L;i<=up;++i){        tmp2 = i%L;        tmp0 =indexs[i-L];        --mp[tmp2][tmp0];        //--vis2[tmp0];        //if(!vis2[tmp0])                  //ff[i] = ff[i-L];        if(!mp[tmp2][tmp0]){            mp[tmp2].erase(tmp0);        }            //--ff[i];        tmp1 = ML;        tmp0 = indexs[i+ML];        if(mp[tmp2].count(tmp0)){           // ++vis2[tmp0];            ++mp[tmp2][tmp0];        }        else {           //[tmp0];            mp[tmp2].insert(pair<int,int>(tmp0,1));            //++ff[i];           // ++ans;            if(mp[tmp2].size()==M){                ++ans;            }        }    }    return ans;}void clear(){//    for(int i=0;i<cnt;++i){//        if(vt1[i].size()){//            vt1[i].clear();//        }//    }}int main(){    //    for(int i=100000;;++i){//        bool flag = true;//        for(int j=2;j<=sqrt(i*1.0);++j){//            if(i%j==0){//                flag = false;//                break;//            }//        }//        if(flag){//            printf("%d\n",i);//            break;//        }//    }    while(scanf("%d%d",&M,&L)!=EOF){        init();        scanf("%s",str);        prepro();       int ans = solve();        printf("%d\n",ans);       // clear();    }    return  0;}


0 0