Trie/Xor

来源:互联网 发布:linux history 参数 编辑:程序博客网 时间:2024/05/13 01:06

题目链接

/*有一个数组a1,a2,a3……an。找到一个连续子段[l,r],使得al ^ al+1 ^……^ ar达到最大。一般思路:维护前缀异或+暴力;for(int i=1;i<=n;i++)    a[i]^=a[i-1];for(int i=1;i<=n;i++)    for(int j=1;j<i;i++)        ans=max(ans,a[i]^a[j]);数据量很大,暴力不行。维护前缀异或+Trie优化;*///指针版本#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=1000000+5;const int si=23;int a[maxn];int n;struct node{    node *chi[2];    void init()    {        chi[0]=NULL;        chi[1]=NULL;    }};void Insert(int k,node * root){    for(int i=si;i>=0;i--)    {        if((k&(1<<i)))        {            if(root->chi[1]==NULL)            {                node *t=(node *)malloc(sizeof(node));                t->init();                root->chi[1]=t;            }            root=root->chi[1];        }        else        {            if(root->chi[0]==NULL)            {                node *t=(node *)malloc(sizeof(node));                t->init();                root->chi[0]=t;            }            root=root->chi[0];        }    }}int query(int k,node *root){    int ret=0;    for(int i=si;i>=0;i--)    {        if(k&(1<<i))//找0        {            if(root->chi[0]!=NULL)            {                root=root->chi[0];            }            else            {                root=root->chi[1];                ret+=(1<<i);            }        }        else//找1        {            if(root->chi[1]!=NULL)            {                root=root->chi[1];                ret+=(1<<i);            }            else            {                root=root->chi[0];            }        }    }    return k^ret;}void rease(node * root){    if(root->chi[0]!=NULL)        rease(root->chi[0]);    if(root->chi[1]!=NULL)        rease(root->chi[1]);    delete root;}int main (){    while(~scanf("%d",&n))    {        node *root=(node *)malloc(sizeof(node));        root->init();        Insert(0,root);        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i]);            a[i]^=a[i-1];            Insert(a[i], root);        }        int ans=0;        for(int i=1;i<=n;i++)        {            ans=max(ans,query(a[i], root));        }        printf("%d\n",ans);        rease(root);    }    return 0;}//数组版本#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=1000000+5;const int si=23;int a[maxn];int tree[maxn*3][2];int cnt=0;int n;void Insert(int k){    int root=0;    for(int i=si;i>=0;i--)    {        if((k&(1<<i)))        {            if(tree[root][1]==0)            {                cnt++;                tree[root][1]=cnt;            }            root=tree[root][1];        }        else        {            if(tree[root][0]==0)            {                cnt++;                tree[root][0]=cnt;            }            root=tree[root][0];        }    }}int query(int k){    int root=0;    int ret=0;    for(int i=si;i>=0;i--)    {        if(k&(1<<i))//找0        {            if(tree[root][0]!=0)            {                root=tree[root][0];            }            else            {                root=tree[root][1];                ret+=(1<<i);            }        }        else//找1        {            if(tree[root][1]!=0)            {                root=tree[root][1];                ret+=(1<<i);            }            else            {                root=tree[root][0];            }        }    }    return k^ret;}int main (){    while(~scanf("%d",&n))    {        memset(tree,0,sizeof(tree));        cnt=0;        Insert(0);        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i]);            a[i]^=a[i-1];            Insert(a[i]);        }        int ans=0;        for(int i=1;i<=n;i++)        {            ans=max(ans,query(a[i]));        }        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击