zoukankan      html  css  js  c++  java
  • Ural 2040. Palindromes and Super Abilities 2 回文自动机

    2040. Palindromes and Super Abilities 2

    题目连接:

    http://acm.timus.ru/problem.aspx?space=1&num=2040

    Description

    Dima adds letters s1, …, sn one by one to the end of a word. After each letter, he asks Misha to tell him how many new palindrome substrings appeared when he added that letter. Two substrings are considered distinct if they are different as strings. Which n numbers will be said by Misha if it is known that he is never wrong?

    Input

    The input contains a string s1 … sn consisting of letters ‘a’ and ‘b’ (1 ≤ n ≤ 5 000 000).

    Output

    Print n numbers without spaces: i-th number must be the number of palindrome substrings of the prefix s1 … si minus the number of palindrome substrings of the prefix s1 … si−1. The first number in the output should be one.

    Sample Input

    abbbba

    Sample Output

    111111

    Hint

    题意

    每次往后增加一个字符的时候,如果本质不同的回文串增加了,那就输出1,否则输出0

    题解:

    回文自动机/回文树裸题,卡了输入输出

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 5e6 + 15;
    
    namespace fastIO{
        #define BUF_SIZE 100000
        #define OUT_SIZE 100000
        #define ll long long
        //fread->read
        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;}
                //{printf("IO error!
    ");system("pause");for (;;);exit(0);}
            }
            return *p1++;
        }
        inline bool blank(char ch){return ch==' '||ch=='
    '||ch=='
    '||ch=='	';}
        inline void read(int &x){
            bool sign=0; char ch=nc(); x=0;
            for (;blank(ch);ch=nc());
            if (IOerror)return;
            if (ch=='-')sign=1,ch=nc();
            for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
            if (sign)x=-x;
        }
        inline void read(ll &x){
            bool sign=0; char ch=nc(); x=0;
            for (;blank(ch);ch=nc());
            if (IOerror)return;
            if (ch=='-')sign=1,ch=nc();
            for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
            if (sign)x=-x;
        }
        inline void read(double &x){
            bool sign=0; char ch=nc(); x=0;
            for (;blank(ch);ch=nc());
            if (IOerror)return;
            if (ch=='-')sign=1,ch=nc();
            for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
            if (ch=='.'){
                double tmp=1; ch=nc();
                for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
            }
            if (sign)x=-x;
        }
        inline void read(char *s){
            char ch=nc();
            for (;blank(ch);ch=nc());
            if (IOerror)return;
            for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
            *s=0;
        }
        inline void read(char &c){
            for (c=nc();blank(c);c=nc());
            if (IOerror){c=-1;return;}
        }
        //getchar->read
        inline void read1(int &x){
            char ch;int bo=0;x=0;
            for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
            for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
            if (bo)x=-x;
        }
        inline void read1(ll &x){
            char ch;int bo=0;x=0;
            for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
            for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
            if (bo)x=-x;
        }
        inline void read1(double &x){
            char ch;int bo=0;x=0;
            for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
            for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
            if (ch=='.'){
                double tmp=1;
                for (ch=getchar();ch>='0'&&ch<='9';tmp/=10.0,x+=tmp*(ch-'0'),ch=getchar());
            }
            if (bo)x=-x;
        }
        inline void read1(char *s){
            char ch=getchar();
            for (;blank(ch);ch=getchar());
            for (;!blank(ch);ch=getchar())*s++=ch;
            *s=0;
        }
        inline void read1(char &c){for (c=getchar();blank(c);c=getchar());}
        //scanf->read
        inline void read2(int &x){scanf("%d",&x);}
        inline void read2(ll &x){
            #ifdef _WIN32
                scanf("%I64d",&x);
            #else
            #ifdef __linux
                scanf("%lld",&x);
            #else
                puts("error:can't recognize the system!");
            #endif
            #endif
        }
        inline void read2(double &x){scanf("%lf",&x);}
        inline void read2(char *s){scanf("%s",s);}
        inline void read2(char &c){scanf(" %c",&c);}
        inline void readln2(char *s){gets(s);}
        //fwrite->write
        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 print(int x){
                static char s[15],*s1;s1=s;
                if (!x)*s1++='0';if (x<0)out('-'),x=-x;
                while(x)*s1++=x%10+'0',x/=10;
                while(s1--!=s)out(*s1);
            }
            void println(int x){
                static char s[15],*s1;s1=s;
                if (!x)*s1++='0';if (x<0)out('-'),x=-x;
                while(x)*s1++=x%10+'0',x/=10;
                while(s1--!=s)out(*s1); out('
    ');
            }
            void print(ll x){
                static char s[25],*s1;s1=s;
                if (!x)*s1++='0';if (x<0)out('-'),x=-x;
                while(x)*s1++=x%10+'0',x/=10;
                while(s1--!=s)out(*s1);
            }
            void println(ll x){
                static char s[25],*s1;s1=s;
                if (!x)*s1++='0';if (x<0)out('-'),x=-x;
                while(x)*s1++=x%10+'0',x/=10;
                while(s1--!=s)out(*s1); out('
    ');
            }
            void print(double x,int y){
                static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
                    1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
                    100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
                if (x<-1e-12)out('-'),x=-x;x*=mul[y];
                ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
                ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
                if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
            }
            void println(double x,int y){print(x,y);out('
    ');}
            void print(char *s){while (*s)out(*s++);}
            void println(char *s){while (*s)out(*s++);out('
    ');}
            void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
            ~Ostream_fwrite(){flush();}
        }Ostream;
        inline void print(int x){Ostream.print(x);}
        inline void println(int x){Ostream.println(x);}
        inline void print(char x){Ostream.out(x);}
        inline void println(char x){Ostream.out(x);Ostream.out('
    ');}
        inline void print(ll x){Ostream.print(x);}
        inline void println(ll x){Ostream.println(x);}
        inline void print(double x,int y){Ostream.print(x,y);}
        inline void println(double x,int y){Ostream.println(x,y);}
        inline void print(char *s){Ostream.print(s);}
        inline void println(char *s){Ostream.println(s);}
        inline void println(){Ostream.out('
    ');}
        inline void flush(){Ostream.flush();}
        //puts->write
        char Out[OUT_SIZE],*o=Out;
        inline void print1(int x){
            static char buf[15];
            char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
            while(x)*p1++=x%10+'0',x/=10;
            while(p1--!=buf)*o++=*p1;
        }
        inline void println1(int x){print1(x);*o++='
    ';}
        inline void print1(ll x){
            static char buf[25];
            char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
            while(x)*p1++=x%10+'0',x/=10;
            while(p1--!=buf)*o++=*p1;
        }
        inline void println1(ll x){print1(x);*o++='
    ';}
        inline void print1(char c){*o++=c;}
        inline void println1(char c){*o++=c;*o++='
    ';}
        inline void print1(char *s){while (*s)*o++=*s++;}
        inline void println1(char *s){print1(s);*o++='
    ';}
        inline void println1(){*o++='
    ';}
        inline void flush1(){if (o!=Out){if (*(o-1)=='
    ')*--o=0;puts(Out);}}
        struct puts_write{
            ~puts_write(){flush1();}
        }_puts;
        inline void print2(int x){printf("%d",x);}
        inline void println2(int x){printf("%d
    ",x);}
        inline void print2(char x){printf("%c",x);}
        inline void println2(char x){printf("%c
    ",x);}
        inline void print2(ll x){
            #ifdef _WIN32
                printf("%I64d",x);
            #else
            #ifdef __linux
                printf("%lld",x);
            #else
                puts("error:can't recognize the system!");
            #endif
            #endif
        }
        inline void println2(ll x){print2(x);printf("
    ");}
        inline void println2(){printf("
    ");}
        #undef ll
        #undef OUT_SIZE
        #undef BUF_SIZE
    };
    using namespace fastIO;
    
    char str[maxn] , output[maxn];
    
    struct Palindromic_Auto{
        const static int LetterSize = 2; // 字符集大小
    	const static int TrieSize = maxn; // 可能的所有节点总数量
    	int tot; // 节点总数
    	int suffixlink[TrieSize]; // 后缀链接
    
    	struct node{
    		int ptr[LetterSize]; // 节点指针
    		int len ; // 长度
    	}tree[TrieSize];
    
    	inline int GetLetterIdx(char c){ // 获取字符哈希,在[0,LetterSize)内
    		return c - 'a';
    	}
    
    	inline void init_node(node & x , int len = 0){
    		memset( x.ptr , 0 , sizeof( x.ptr ) );
    		x.len = len ;
    	}
    
    	void insert( const char * str ){
    		int len = strlen( str );
    		int j = 0 ;
    		for(int i = 0 ; i < len ; ++ i){
    			int idx = GetLetterIdx( str[i] );
    			for( ; i-tree[j].len-1 < 0 || str[i]!=str[i-tree[j].len-1] ; j=suffixlink[j]); //Max Math for suffixlink
    			if(tree[j].ptr[idx]){
    				j = tree[j].ptr[idx];
    				output[i] = '0';
    				continue;
    			}
    			output[i] = '1';
    			int cur = j;
    			init_node( tree[tot] , tree[cur].len + 2 ); tree[cur].ptr[idx]=tot,j=tot++;
    			if( tree[j].len == 1 ){
    				suffixlink[j] = 1;
    				continue;
    			}
    			for( cur = suffixlink[cur] ; i - tree[cur].len - 1 < 0 || str[i]!= str[i-tree[cur].len-1] ; cur = suffixlink[cur] );
    			suffixlink[j]=tree[cur].ptr[idx];
    		}
    	}
    
    	void init(){
    		tot = 0 ;
    		init_node( tree[tot ++ ] , -1 );
    		init_node( tree[tot ++ ] , 0 );
    	}
    }pa_auto;
    
    int main(int argc,char *argv[]){
    	read(str);
    	pa_auto.init();
    	pa_auto.insert( str );
    	println(output);
    	return 0;
    }
  • 相关阅读:
    linux常用的一些访问目录
    专业术语
    java基础知识回顾之javaIO类--File类应用:获取指定目录下面的指定扩展名的文件,将文件的绝对路径写入到目的文件当中
    java基础知识回顾之javaIO类--File类应用:删除带内容的目录
    java基础知识回顾之javaIO类--File类应用:过滤器接口FilenameFilter和FileFilter
    java基础知识回顾之javaIO类--File类应用:递归深度遍历文件
    java基础知识回顾之javaIO类--File类
    java基础知识回顾之java集合类-Properties集合
    java基础知识回顾之---java StringBuffer,Stringbuilder与String的区别
    java基础知识回顾之---java StringBuilder与StringBuffer异同点
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5742567.html
Copyright © 2011-2022 走看看