Problem A 腿部挂件

  给出$n$个数的序列$a_i$,支持$T$次操作。

  每次操作形如$x , l , r$,计算$\max_{i = l}^{r} (a_i \oplus x)$的值。

  对于$100\%$的数据满足$1 \leq n \leq 2 \times 10^5 , 0 \leq a_i \leq 10^9$

Solution : 

  通常可以使用可持久化字典树求解,但是这里可以用字典树套vector来做。

  这样当当前节点vector有一个在$l,r$的数中就往下走,还是按照以前的贪心策略,从高位到低位贪心。

  这样做的时间复杂度是$O(n {log_2} ^2 n)$

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
struct node
{
    vector<int>p;
    int ls,rs;
    node(){ls=rs=-1;}
}tr[6100000];
int n,m,a,x,y,cnt,o[50];
void push(int k,int p)
{
    for(int i=30-1,nw=1;i>=0;i--)
    {
        if(k&o[i])
        {
            if(tr[nw].ls==-1)tr[nw].ls=++cnt;
            nw=tr[nw].ls;
        }
        else
        {
            if(tr[nw].rs==-1)tr[nw].rs=++cnt;
            nw=tr[nw].rs;
        }
        tr[nw].p.pb(p);
    }
}
int query(int k,int l,int r)
{
    int ans=0;
    for(int i=30-1,nw=1;i>=0;i--)
    {
        if(k&o[i])
        {
            if(tr[nw].rs==-1||*(tr[tr[nw].rs].p.end()-1)<l||*lower_bound(tr[tr[nw].rs].p.begin(),tr[tr[nw].rs].p.end(),l)>r)
                nw=tr[nw].ls,ans+=o[i];
            else nw=tr[nw].rs;
        }
        else
        {
            if(tr[nw].ls==-1||*(tr[tr[nw].ls].p.end()-1)<l||*lower_bound(tr[tr[nw].ls].p.begin(),tr[tr[nw].ls].p.end(),l)>r)
                nw=tr[nw].rs;
            else nw=tr[nw].ls,ans+=o[i];
        }
    }
    return ans^k;
}
int main()
{
    freopen("hugclose.in","r",stdin);
    freopen("hugclose.out","w",stdout);
    scanf("%d%d",&n,&m),o[0]=cnt=1;
    for(int i=1;i<30;i++)o[i]=o[i-1]*2;
    for(int i=1;i<=n;i++)scanf("%d",&a),push(a,i);
    for(int i=1;i<=m;i++)scanf("%d%d%d",&a,&x,&y),printf("%d\n",query(a,x+1,y+1));
    return 0;
}
hugclose.cpp

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案