Niuke.com Niuke practice match 16 E. Evaluation

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

Time limit: C/C++ 1 second, other languages ​​2 seconds
Space limit: C/C++ 32768K, other languages ​​65536K
64bit IO Format: %lld
title description
Given n numbers a1, a2, ..., an.
Define f(l, r) = al | al+1| ... | ar.
Now enumerate (1 <= l <= r <= n) and ask how many different f values ​​there are.
Input description:

In the first line, an integer n represents the size of the array (1 <= n <= 100,000); in
the second line, n integers satisfy 0 <= ai <= 1000,000.

Output description:

Output an integer indicating how many different f values ​​there are.

Example 1
Input

3
1 2 0

Output

4

Example 2
Input

10
1 2 3 4 5 6 1 2 9 10

Output

11

 

Analysis: It can be found that according to the scope of the topic, each number has a maximum of 20 binary digits, so we can first enumerate the numbers at the beginning of each interval. For example, if i is enumerated now, it will generate the next position of the new value. The number should be on the binary bit where i is 0, the bit of the new number should be 1, and in order not to miss, the new number must be the nearest. . In order to find the nearest position, preprocessing can be performed, Next[i][j] is used to represent the nearest position starting from the i-th number and the j-th binary bit is 1, so the time complexity is O ( 20*20*n), can satisfy.

code show as below:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const int MAXN=1e5+100;
int vis[1000010*2];
int Next[MAXN][22];
int a[MAXN];
int tmp;
int main()
{
    int n;
    int ans= 0 ;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
    scanf("%d",&a[i]);
     if(a[i]==0&&!vis[0])
     {
     vis[0]=1;
     years ++ ;
     }
    }

    for(int i=0;i<=19;i++)
    {
      if(a[n]&(1<<i))
      Next[n][i]=n;
      else
      Next[n][i]=n+1;
    }
    for(int i=n-1;i>=1;i--)
    {
        for(int j=0;j<=19;j++)
        {
           if(a[i]&(1<<j))
           Next[i][j]=i;
           else
           Next[i][j]=Next[i+1][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
       int p=i;
       int now=0;
       while(1)
       {

          int minpos=MAXN;

          for(int j=0;j<=19;j++)
          {
              if(!(now&(1<<j)))
              minpos=min(minpos,Next[p][j]);
          }
          if(minpos>n)break;
          now|=a[minpos];
          if(!vis[now])
          {
              vis[now]=1;
              years ++ ;
          }
          p=minpos;
       }
    }
    printf("%d\n",ans);

    return 0;
}

 

Guess you like

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