zoukankan      html  css  js  c++  java
  • 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=='
    '||ch=='
    '||ch=='	';}
        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('
    ');}
        inline void flush(){Ostream.flush();}
        char Out[OUT_SIZE],*o=Out;
        inline void print1(char c){*o++=c;}
        inline void println1(){*o++='
    ';}
        inline void flush1(){if (o!=Out){if (*(o-1)=='
    ')*--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;
    }
    

      

  • 相关阅读:
    一个关于STL list使用 小示例
    c++几个通用工具
    修改pc机的mac地址 以及 mac地址的组成
    win7 下 arp 绑定mac和Ip
    wireshark如何抓取别人电脑的数据包
    WPA破解原理简要——无线网络破解续
    Apache配置代理服务器的方法(2)
    Apache配置代理服务器的方法(1)
    在Linux系统中如何设置APACHE服务器里的后台页面只允许某个IP地址访问
    Apache服务器配置技巧
  • 原文地址:https://www.cnblogs.com/forever97/p/hdu5972.html
Copyright © 2011-2022 走看看