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; }