HDU 5972 Regular Number(ShiftAnd+读入优化)

Posted forever97‘s blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5972 Regular Number(ShiftAnd+读入优化)相关的知识,希望对你有一定的参考价值。

 

【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5972

 

【题目大意】

  给出一个字符串,找出其中所有的符合特定模式的子串位置,符合特定模式是指,该子串的长度为n,并且第i个字符需要在给定的字符集合Si中 

 

【题解】

  利用ShiftAnd匹配算法。

  bt[i]表示字符i允许在哪些位置上出现,我们将匹配成功的位置保存在dp中,那么就可以用dp[i]=dp[i-1]<<1&bt[s[i]]来更新答案了

  利用滚动数组和bitset可以来优化这样的运算,当一个位置的匹配在更新的过程中没有丢失,

  即始终在特定模式中直到定长,那么这个位置就是成功匹配位,复杂度为O(nm/64)

  由于输入的数据量庞大,因此需要读入和输出优化。

  终于AC了,补上大连赛区的遗憾。

 

【代码】

#include <cstdio>
#include <bitset>
#include <cstring>
using namespace std;
const int M=1010,N=5000010,U=256;
bitset<M> dp[2],bt[U];
int n,m,x,id[U],cnt,l;
char s[N];
namespace fastIO{
    #define BUF_SIZE 100000
    #define OUT_SIZE 1000000
    bool IOerror=0;
    inline char nc(){
        static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
        if(p1==pend){
            p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
            if (pend==p1){IOerror=1;return -1;}
        }return *p1++;
    }
    inline bool blank(char ch){return ch==‘ ‘||ch==‘\n‘||ch==‘\r‘||ch==‘\t‘;}
    inline int read(char *s){
        char ch=nc();
        for(;blank(ch);ch=nc());
        if(IOerror)return 0;
        for(;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
        *s=0;
        return 1;
    }
    inline int RI(int &a){
        char ch=nc(); a=0;
    	for(;blank(ch);ch=nc());
    	if(IOerror)return 0;
    	for(;!blank(ch)&&!IOerror;ch=nc())a=a*10+ch-‘0‘;
    	return 1;
    }
    struct Ostream_fwrite{
        char *buf,*p1,*pend;
        Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
        void out(char ch){
            if (p1==pend){
                fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
            }*p1++=ch;
        }
        void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
        ~Ostream_fwrite(){flush();}
    }Ostream;
    inline void print(char x){Ostream.out(x);}
    inline void println(){Ostream.out(‘\n‘);}
    inline void flush(){Ostream.flush();}
    char Out[OUT_SIZE],*o=Out;
    inline void print1(char c){*o++=c;}
    inline void println1(){*o++=‘\n‘;}
    inline void flush1(){if (o!=Out){if (*(o-1)==‘\n‘)*--o=0;puts(Out);}}
    struct puts_write{
        ~puts_write(){flush1();}
    }_puts;
};
void init(){
    cnt=0;
    for(int i=‘0‘;i<=‘9‘;i++)id[i]=cnt++;
}
void ShiftAnd(int n,int m){
    int cur=1,f=0;
    dp[0].reset(); dp[0].set(0);
    for(int i=1;i<=n;i++,cur^=1){
        dp[cur]=dp[cur^1]<<1&bt[id[s[i]]];
        dp[cur].set(0);
        if(dp[cur][m]){
            for(int j=i-m+1;j<=i;j++)fastIO::print(s[j]);
            fastIO::println();
        }
    }
}
int main(){   
    //freopen("demo.in","r",stdin);
    //freopen("demo.out","w",stdout);
    init();
    while(fastIO::RI(m)){ 
        for(int i=0;i<cnt;i++)bt[i].reset();
        for(int i=1;i<=m;i++){
            fastIO::RI(l);
            for(int j=1;j<=l;j++){
                fastIO::RI(x);
                bt[x].set(i);
            }
        }fastIO::read(s+1); 
        n=strlen(s+1);
        ShiftAnd(n,m);
    }return 0;
}

  

以上是关于HDU 5972 Regular Number(ShiftAnd+读入优化)的主要内容,如果未能解决你的问题,请参考以下文章

Regular Number HDU - 5972

HDU 5972 Regular Number

hdu 5972---Regular Number(字符串匹配)

HDU 5972 Regular Number(ShiftAnd+读入优化)

Regular Number hdu-5972(bitset+Shift-And算法)

Shift - And字符串快速处理 hdu5972+cf