Luo Gu P4735 solution to a problem

If you want in-depth study can be persistent 0-1Trie trees portal .


Description:

A given number of columns \ (\ {A_N \} \) , supports two modes of operation:

  • Add the number of columns in a number of tail \ (X \) , the number of column length becomes \ (n-+. 1 \) ;
  • Given the closed interval \ ([l, r] \ ) and a number \ (X \) , requirements:

\[ \max_{i=l}^{r}\left \{\left(\bigoplus_{j=i}^{n}a_j \right)\bigoplus x\right \} \]

Method:

Defined \ (Xorsum_i \) of \ (\ bigoplus_. 1 = {I}} ^ {n-a_i \) , i.e. the prefix and XOR. Obviously, we can get
\ [\ left (\ bigoplus_ { i = pos} ^ {n} a_i \ right) \ bigoplus x = Xorsum_ {pos-1} \ bigoplus Xorsum_n \ bigoplus x \]

NOTE : \ (X \ Bigoplus X = 0 \) , \ (X \ Bigoplus 0 = X \)

We found \ (Xorsum_n \ bigoplus x \) is a fixed value , we only need to maintain \ (Xorsum_ {pos-1} \) can.

May consider using persistence 0-1Trie tree maintenance. Chairman of the tree the same way, we build \ (n + 1 \) version of 0-1Trie tree, when the query using greedy ideas can be.

Persistence segment tree can also support " prefix and " thinking, we need only last the first \ (r \) version of 0-1Trie trees look \ (l \) to position.

This topic cancer card often, IConstant big ugly man, With the freadother cards through normal operation only. And becauseThe reason luogu evaluation Kyi(Fog, the code will have been passed out Twoc. But then the card, open o2it.

Code:

#include<bits/stdc++.h>
#define Maxn 600010
#define Maxdep 23
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
inline void read(int &x)
{
    int f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
int n,m;
int sum[Maxn];
struct trie
{
    trie *chd[2];
    int symbl;
    trie()
    {
        for(int i=0;i<2;i++) chd[i]=NULL;
        symbl=0;
    }
}*root[Maxn],tree[Maxn<<5],*tail;
void Init(){tail=tree;} 
void build(trie *&p,int dep)
{
    p=new (tail++)trie();
    if(dep<0) return ;
    build(p->chd[0],dep-1);
}
void update(trie *&p,trie *flag,int dep,int i)
{
    p=new (tail++)trie();
    if(flag) *p=*flag;
    if(dep<0) return (void)(p->symbl=i);
    int tmp=(sum[i]>>dep)&1;//判断是1还是0 
    if(!tmp) update(p->chd[0],flag?flag->chd[0]:NULL,dep-1,i);
    else update(p->chd[1],flag?flag->chd[1]:NULL,dep-1,i);
    if(p->chd[0]) p->symbl=std::max(p->symbl,p->chd[0]->symbl);
    if(p->chd[1]) p->symbl=std::max(p->symbl,p->chd[1]->symbl);
}
int query(trie *p,int x,int dep,int limit)
{
    if(dep<0) return sum[p->symbl]^x;
    int tmp=(x>>dep)&1;
    if(p->chd[tmp^1]&&p->chd[tmp^1]->symbl>=limit) return query(p->chd[tmp^1],x,dep-1,limit);
    return query(p->chd[tmp],x,dep-1,limit);
}
signed main()
{
    Init();
    read(n),read(m);
    build(root[0],Maxdep);
    for(int i=1,x;i<=n;i++)
    {
        read(x);
        sum[i]=sum[i-1]^x;
        update(root[i],root[i-1],Maxdep,i);
    } 
    for(int i=1;i<=m;i++)
    {
        char ch=getchar();
        while(ch!='A'&&ch!='Q') ch=getchar();
        if(ch=='A')
        {
            int x;
            read(x);
            n++;
            sum[n]=sum[n-1]^x;
            update(root[n],root[n-1],Maxdep,n); 
            continue;
        }   
        if(ch=='Q')
        {
            int l,r,x;
            read(l),read(r),read(x);
            int ans=query(root[r-1],sum[n]^x,Maxdep,l-1);
            printf("%d\n",ans);
            continue;
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/nth-element/p/11785037.html