牛客练习赛16-E-求值(瞎搞)

链接: 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值一共有多少个。

输入描述:

第一行一个整数n表示数组大小 (1 <= n <= 100,000);
第二行n个整数满足0 <= ai <= 1000,000。

输出描述:

输出一个整数表示不同的f值一共有多少个。

题解:枚举右端点,然后每次往前找,并去掉没有贡献的若干值,因为区间是连续的,它对当前没贡献的话,对之后也不可能有贡献,所以留下的都是对之后可能有贡献的,然后每次暴力遍历即可,当然本身没出现过的话也要++。

#include
#include
#include
#include
using namespace std;
vectorq;
int n,m,ans,vis[2500005];
int find(int x)
{
	for(int i=q.size()-1;i>=0;i--)
	{
		if((x|q[i])==x)
		{
			q.erase(q.begin()+i);
			return 0;
		}
		x|=q[i];
	}
	return 1;
}
int main(void)
{
	int x;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&x);
		while(1)
		{
			if(find(x))
				break;
		}
		if(vis[x]==0)
			ans++,vis[x]=1;
		int t=x;
		for(int j=q.size()-1;j>=0;j--)
		{
			x|=q[j];
			if(vis[x]==0)
				ans++,vis[x]=1;
		}
		q.push_back(t);
	}
	printf("%d\n",ans);
	return 0;
}

你可能感兴趣的:(暴力)