Niuke.com Wannafly Challenge 14 E. Invalid position (union set + linear basis)

Link: https://www.nowcoder.com/acm/contest/81/E
Source : Niuke.com

Title Description

Give a 1-base array {a}, there are N operations, each operation will invalidate a position. The weight of an interval is defined as the maximum value of the XOR sum of selected numbers in this interval. Find the maximum value of the weights of all intervals that do not contain invalid positions before each operation.
Input description:

The first line reads a positive integer (1 <= n <= 105)

The second line reads n positive integers, the i-th represents a[i] (0<= a[i] <= 109)

The third line reads n positive integers, the i-th represents the position of x[i], which is the i-th operation, ensuring that x[i] are different from each other.

Output description:

Output n lines Answer

Example 1
Input

10
169 816 709 896 58 490 97 254 99 796
4 2 3 10 5 6 1 8 9 7

Output

1023
994
994
994
490
490
254
254
99
97

analyze:

According to the title, a linear basis can be thought of, and because forward deletion is not easy to handle, it can be inserted in reverse offline.

After each insertion, the answer may retain the original maximum value, or the insertion position may constitute a new maximum value.

Then we need to discuss the position of insertion and whether it constitutes a new interval with the left and right. If the current insertion position is x, we need to see if there is a value on x+1. If there is a value, we need to merge the linear basis. Take the leftmost position of the interval as the combined linear basis. A union can be used to maintain this location. Then see if there is a value at the x-1 position, and if so, perform a linear basis merging in the same way.

Finally, output the maximum value of the linear basis obtained.

code show as below:

#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <vector>
#include <stack>
#include <cstring>
using namespace std;
const int MAXN=1e5+100;
typedef long long LL ;
int pre[MAXN];
int vis[MAXN];
LL  a[MAXN];

int Find(int x)
{
    int h,tmp;
    h=x;
   while(x!=pre[x])
     x=pre[x];
   while(x!=h)
   {
      tmp=pre[h];
      pre[h]=x;
      h=tmp;
   }
   return x;
}

void join(int x,int y)
{
    int p=Find(x);
    int q=Find(y);
    if(p<q)
    pre[q]=p;
    else if(p>q)
    pre[p]=q;
}
struct node
{
    LL  id;
    LL  x;
    LL  ans;
} qes [MAXN];
struct L_B{
    long long d[61],p[61];
    int cnt;
    L_B()
    {
        cnt=0;
    }
    bool insert(long long val)
    {
        for (int i=60;i>=0;i--)
            if (val&(1LL<<i))
            {
                if (!d[i])
                {
                    d[i]=val;
                    break;
                }
                val^=d[i];
            }
        return val>0;
    }
    long long query_max()
    {
        long long ret=0;
        for (int i=60;i>=0;i--)
            if ((ret^d[i])>ret)
                ret ^ = d [i];
        return ret;
    }
    long  long query_min()
    {
        for (int i=0;i<=60;i++)
            if (d[i])
                return d[i];
        return 0;
    }
    void rebuild()
    {
        for (int i=60;i>=0;i--)
            for (int j=i-1;j>=0;j--)
                if (d[i]&(1LL<<j))
                    d[i]^=d[j];
        for (int i=0;i<=60;i++)
            if (d[i])
                p[cnt++]=d[i];
    }
    long  long kthquery( long  long k)
    {
        long long ret=0;
        if (k>=(1LL<<cnt))
            return -1;
        for (int i=60;i>=0;i--)
            if (k&(1LL<<i))
                ret ^ = p [i];
        return ret;
    }
};
L_B merge(const L_B &n1,const L_B &n2)
{
    L_B ret=n1;
    for (int i=60;i>=0;i--)
        if (n2.d[i])
            ret.insert(n2.d[i]);
    return ret;
}
LL  n;
L_B A[MAXN];
intmain ()
{

     LL ans=0;
     scanf("%lld",&n);
     for(int i=1;i<=n;i++)
     {
      pre[i]=i;
     scanf("%lld",&a[i]);
     }
     for(int i=1;i<=n;i++)
     {
        qes[i].id=i;
        scanf("%lld",&qes[i].x);
     }

    for(int i=n;i>=1;i--)
     {
        A[qes[i].x].insert(a[qes[i].x]);
        vis [qes [i] .x] = 1 ;
        if (vis [qes [i] .x + 1 ])
        {
         A[Find(qes[i].x)]=merge(A[Find(qes[i].x)],A[Find(qes[i].x+1)]);
         join(qes[i].x,qes[i].x+1);
        }
         if(vis[qes[i].x-1])
        {
         A[Find(qes[i].x-1)]=merge(A[Find(qes[i].x-1)],A[Find(qes[i].x)]);
         join(qes[i].x,qes[i].x-1);
        }
        ans=max(ans,A[Find(qes[i].x)].query_max());
        qes[i].ans = years;
     }
     for(int i=1;i<=n;i++)
    cout<<qes[i].ans<<endl;
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324903107&siteId=291194637