链接:https://www.nowcoder.com/acm/contest/84/E
来源:牛客网
题目描述
给定n个数字a
1, a
2, ..., a
n。
定义f(l, r) = a l | a l+1| ... | a r。
现在枚举(1 <= l <= r <= n),问不同的f值一共有多少个。
定义f(l, r) = a l | a l+1| ... | a r。
现在枚举(1 <= l <= r <= n),问不同的f值一共有多少个。
输入描述:
第一行一个整数n表示数组大小 (1 <= n <= 100,000); 第二行n个整数满足0 <= ai <= 1000,000。
输出描述:
输出一个整数表示不同的f值一共有多少个。
枚举一下左端点,每次增加一个a[i]时,会让总的元素个数最多增加n-i+1个。用map哈希一下即可。
对于p=0,a[i]=101(二进制),他只会把mp[1]集合中所有数的第一位和第三位变成1然后存到mp[0],集合mp[0]的元素个数最多有mp[1]+1个。最坏的情况是每次mp中元素个数每次增加一个,那么最坏复杂度是(100000+1)/2。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
ll a[100005];
int n,p;
map<ll,ll> mp[2];
map<ll,ll> m;
int main()
{
scanf("%d", &n);
for(int i = 1 ; i <= n ; ++ i)
scanf("%lld", &a[i]);
mp[0][a[n]]=1;
m[a[n]]=1;
for(int i=n-1;i>=1;--i)
{
p^=1;
mp[p].clear();
mp[p][a[i]]=1;
m[a[i]]=1;
for(map<ll, ll>::iterator it = mp[p^1].begin();it!=mp[p ^ 1].end();++it)
{
m[a[i]|(it->first)]=1;
mp[p][a[i]|(it->first)]=1;
}
cout<<mp[p].size()<<endl;
}
printf("%d\n", m.size());
}