• 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;
    }
  • 相关阅读:
    1.18
    人月神话读后感
    疯狂学java的第45天
    学Java的第46天
    JAVA学习日记150720
    JAVA学习日记140719
    JAVA学习日记160721
    JAVA学习日记130718
    Windows DOS窗体下Oracle 数据库的导入导出(IMP/EXP)命令
    IntelliJ IDEA自动清除没用的import
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5742567.html
Copyright © 2020-2023  润新知