[SCU 4503] TooEasy Or TooDifficult (Manacher+xor-Trie)

来源:互联网 发布:中国著名网络主持人 编辑:程序博客网 时间:2024/04/29 21:40

SCU - 4503

板子题,依题意描述分为三个步骤
1. 求每个位置为中心的回文串,以及最大回文串
2. 求每个回文串的长度的异或前缀和
3. 求两个异或前缀和异或的最大值 (xor-Trie)

然后用快速幂算出 JD,再和 FJD比大小即可

注意一下 Trie上要先插入一个 0

#pragma comment(linker, "/STACK:102400000,102400000")#include <cstdio>#include <iostream>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <map>#include <set>#include <queue>using namespace std;typedef pair<int,int> Pii;typedef long long LL;typedef unsigned long long ULL;typedef double DBL;typedef long double LDBL;#define MST(a,b) memset(a,b,sizeof(a))#define CLR(a) MST(a,0)#define Sqr(a) (a*a)const int maxl=1e5+10;struct Manacher{    char *str;    int *mana,len,res;    Manacher(char *,int);    ~Manacher(){delete []str;delete []mana;}    int query(int);};struct Trie{    struct node    {        char chr;        int val,nxt[2];    } *trie;    int siz;    Trie(int size){trie=new node[size];memset(trie,0,sizeof(node)*size);siz=0;}    ~Trie(){delete []trie;}    int chnum(char x){return x-'0';}    void addstr(char*);    int query(char *str);};char inpt[maxl];int mana[maxl];char str01[50];int spr_pow(int,LL,int);char* nts(int,char*);int main(){    int T;    scanf("%d", &T);    for(int ck=1; ck<=T; ck++)    {        scanf(" %s", inpt);        int len=strlen(inpt);        Manacher mana(inpt,len);        int JD=(LL)spr_pow(mana.res,(LL)len*len*len,mana.res/3*5+1)+mana.res*4/5;        Trie trie(3e5);        int pxor=0,FJD=pxor;        trie.addstr(nts(0,str01));        #ifdef LOCAL        for(int i=1; i<2*len+2; i++) printf("%c ", mana.str[i]);puts("");        for(int i=1; i<2*len+1; i++) printf("%d ", mana.mana[i]);puts("");        #endif        for(int i=0; i<len; i++)        {            pxor^=mana.query(i);//          printf("i_len: %d\n", mana.query(i));            nts(pxor,str01);            FJD=max(FJD, trie.query(str01));            trie.addstr(str01);        }        if(JD>FJD) puts("liujc");        else puts("luoxinchen");    }    return 0;}int spr_pow(int num,LL mi,int MOD){    int res=1;    while(mi)    {        if(mi&1) res=((LL)res*num)%MOD;        num=((LL)num*num)%MOD;        mi>>=1;    }    return res;}Manacher::Manacher(char *tstr,int tlen):len(tlen){    str=new char[2*len+10];    mana=new int[2*len+10];    res=0;    str[0]='!';    for(int i=0; i<len; i++)    {        str[2*i+1]='#';        str[2*i+2]=tstr[i];    }    str[2*len+1]='#';    str[2*len+2]=0;    mana[1]=1;    int p=1,rm=1;    for(int i=2; i<2*len+1; i++)    {        if(rm>i)            mana[i] = min(rm-i+1, mana[2*p-i]);        else            mana[i]=1;        while(str[i-mana[i]] == str[i+mana[i]])            mana[i]++;        if(i+mana[i]-1>rm)        {            rm=i+mana[i]-1;            p=i;        }        if(res<mana[i]) res=mana[i];    }    res--;}int Manacher::query(int np){    return mana[2*np+2]-1;}void Trie::addstr(char *str){    int len=strlen(str),np=0;    for(int i=0; i<len; i++)    {        int ch=chnum(str[i]);        if(trie[np].nxt[ch]) np=trie[np].nxt[ch];        else        {            trie[np].nxt[ch]=++siz;            np=siz;            trie[np].chr=str[i];        }    }}int Trie::query(char *str){    int res=0,np=0;    for(int i=0; i<31; i++)    {        int now=str[i]-'0';        if(trie[np].nxt[now^1])        {            np=trie[np].nxt[now^1];            res^=1<<(30-i);        }        else if(trie[np].nxt[now])        {            np=trie[np].nxt[now];        }    }    return res;}char* nts(int num, char str[]){    for(int i=30; i>=0; i--){str[i]=(num&1)+'0';num>>=1;}    str[31]=0;    return str;}
0 0
原创粉丝点击