Codeforces G. The Brand New Function(枚举)
题目描述:
The Brand New Function
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Polycarpus has a sequence, consisting of n non-negative integers: a1, a2, ..., a**n.
Let's define function f(l, r) (l, r are integer, 1 ≤ l ≤ r ≤ n) for sequence a as an operation of bitwise OR of all the sequence elements with indexes from l to r. Formally: f(l, r) = a**l | a**l + 1 | ... | a**r.
Polycarpus took a piece of paper and wrote out the values of function f(l, r) for all l, r (l, r are integer, 1 ≤ l ≤ r ≤ n). Now he wants to know, how many distinct values he's got in the end.
Help Polycarpus, count the number of distinct values of function f(l, r) for the given sequence a.
Expression x | y means applying the operation of bitwise OR to numbers x and y. This operation exists in all modern programming languages, for example, in language C++ and Java it is marked as "|", in Pascal — as "or".
Input
The first line contains integer n (1 ≤ n ≤ 105) — the number of elements of sequence a. The second line contains n space-separated integers a1, a2, ..., a**n (0 ≤ a**i ≤ 106) — the elements of sequence a.
Output
Print a single integer — the number of distinct values of function f(l, r) for the given sequence a.
Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use cin, cout streams or the %I64d specifier.
Examples
Input
Copy
3
1 2 0
Output
Copy
4
Input
Copy
10
1 2 3 4 5 6 1 2 9 10
Output
Copy
11
Note
In the first test case Polycarpus will have 6 numbers written on the paper: f(1, 1) = 1, f(1, 2) = 3, f(1, 3) = 3, f(2, 2) = 2, f(2, 3) = 2, f(3, 3) = 0. There are exactly 4 distinct numbers among them: 0, 1, 2, 3.
思路:
这道题刚开始觉得呀!肯定非常繁。但之后再想就有点想法了。想法来自于一个我之前想到的或的性质,就是一个数或另一个数结果是大于等于这两个数,也就是或起来只能增加或不变。然后又想到了题目让求几种可能的值。想到如果把所有数都或起来,那么得到的就是最大值。其次是每个数单独与自己或还是自己,于是有几个不同的数就可以在结果上先加上几。一看数的大小也就\(10^6\),那么或的最大个数也就是\(1111111\)个。可以用一个数组直接标记已获得了哪些值。最后就是想到二重循环,遍历每一种可能。但这样肯定超时啊。再想想。在胡思乱想想能不能用线性时间求解时想到了一个思路,是这样的:从头开始,进行累计或运算,每次把当前或的值与下一个或会得到的值做个比较,如果出现当前值等于下一次或的值时,我们可以说在这个位置及以前的累计值暂时做完了贡献,为什么是暂时呢?因为后面出现的数有可能还会改变这个值。
优化的思想与上面的原理相似,就是排除贡献做完的情况。我在计算或值时用两个变量,一个初始值是起点的值,另一个初始值为零。如果我在累计或值的时候发现两个或值竟然相等了,说明什么?说明起点的值完全没有起到作用对不对?它的贡献相对于后面是零,也就是说我用不用这个数对到两个值相等的后面位置没影响。那就可以跳出循环继续以下一个数为起点计算之后的或值。
网上关于这个优化的解释是数全为一后或它就是本身之类的,但我觉得好像是错的。因为我按照这种解释把这个优化变了一下形,把\(1111111\)之内二进制全为1的数预处理出来,累计或值过程中遇到这样的数就跳出循环,但在样例下得到的答案并不对。然后仔细想了想应该是上面那种解释。
代码:
#include <iostream>
#include <cstdio>
#define max_n 100005
using namespace std;
int n;
int a[max_n];
int cnt[1111112];
int cou = 0;
inline void read(int& x)
{
x=0;int f=0;char ch=getchar();
while('0'>ch||ch>'9'){if(ch=='-')f=1;ch=getchar();}
while('0'<=ch&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
x=f?-x:x;
}
int main()
{
read(n);
for(int i = 0;i<n;i++)
{
read(a[i]);
if(cnt[a[i]]==0)
{
cnt[a[i]]=1;
cou++;
}
}
for(int i = 0;i<n;i++)
{
int last = a[i];
int prime = 0;
for(int j = i+1;j<n;j++)
{
last |= a[j];
if(cnt[last]==0)
{
cnt[last] = 1;
cou++;
}
prime |= a[j];
//cout << "last " << last << endl;
if(last==prime)
{
break;
}
}
}
printf("%d",cou);
return 0;
}
参考文章
关于优化的解释不对就不放了吧。
Codeforces G. The Brand New Function(枚举)的更多相关文章
- Codeforces243A The Brand New Function
A. The Brand New Function time limit per test 2 seconds memory limit per test 256 megabytes input st ...
- CodeForces 444C. DZY Loves Physics(枚举+水题)
转载请注明出处:http://blog.csdn.net/u012860063/article/details/37509207 题目链接:http://codeforces.com/contest/ ...
- Codeforces H. Prime Gift(折半枚举二分)
题目描述: Prime Gift time limit per test 3.5 seconds memory limit per test 256 megabytes input standard ...
- Codeforces Gym 100187M M. Heaviside Function two pointer
M. Heaviside Function Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/ ...
- codeforces 678D D. Iterated Linear Function(水题)
题目链接: D. Iterated Linear Function time limit per test 1 second memory limit per test 256 megabytes i ...
- Codeforces 626D Jerry's Protest(暴力枚举+概率)
D. Jerry's Protest time limit per test:2 seconds memory limit per test:256 megabytes input:standard ...
- D. Diverse Garland Codeforces Round #535 (Div. 3) 暴力枚举+贪心
D. Diverse Garland time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Codeforces gym101612 L.Little Difference(枚举+二分)
传送:http://codeforces.com/gym/101612 题意:给定一个数n(<=1e18),将n分解为若干个数的成绩.要求这些数两两之间的差值不能大于1. 分析: 若n==2^k ...
- Codeforces 734C Anton and Making Potions(枚举+二分)
题目链接:http://codeforces.com/problemset/problem/734/C 题目大意:要制作n个药,初始制作一个药的时间为x,魔力值为s,有两类咒语,第一类周瑜有m种,每种 ...
随机推荐
- Bootstrap-table 单元格合并 、表头合并
1.页面引入js/css @*1.Jquery组件引用*@ <script src="~/Scripts/jquery-1.10.2.js"></script&g ...
- [LeetCode] 871. Minimum Number of Refueling Stops 最少的加油站个数
A car travels from a starting position to a destination which is target miles east of the starting p ...
- 面试官:”准备用HashMap存1w条数据,构造时传10000会触发扩容吗?“
通常在初始化 HashMap 时,初始容量都是根据业务来的,而不会是一个固定值,为此我们需要有一个特殊处理的方式,就是将预期的初始容量,再除以 HashMap 的装载因子,默认时就是除以 0.75. ...
- HUSKY CLOCK1.0上线啦!
有人需要HUSKY CLOCK1.0下载资源的请联系1335415335@qq.com! 感谢支持,您的认可是我们前进的动力!
- NPOI中的PhysicalNumberOfCells 与 LastCellNum
这两个理论上一个是算空列,一个不算空列,但是实际上有时候相同数据的excel,不同的excel编辑工具保存后的,PhysicalNumberOfCells可能不一样,会导致莫名其妙错误,最好使用Las ...
- Java如何执行操作系统的CMD命令行
在模拟cmd调用Python时遇到一些情况,这类问题可以归类为"超时,阻塞"等,问题原因: Process p=Runtime.getRuntime().exec(String[] ...
- 在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证
基于令牌的身份验证 基于令牌的身份验证主要区别于以前常用的常用的基于cookie的身份验证,基于cookie的身份验证在B/S架构中使用比较多,但是在Web Api中因其特殊性,基于cookie的身份 ...
- 03 .NET CORE 2.2 使用OCELOT -- Docker中的Consul
部署consul-docker镜像 先搜索consul的docker镜像 docker search consul 然后选择了第一个,也就是官方镜像 下载镜像 docker pull consul 然 ...
- 代码语法高亮踩坑-原理,问题, PRE元素及htmlentity
语法高亮库基础原理 在研究使用能够在web页面上代码语法高显的解决方案时,发现有很多现成的开源库.比较中意的有prism.js,highlightjs.他们的原理基本上核心就两点: 1. 利用html ...
- 基于vue+springboot+docker网站搭建【六】安装中间件
安装中间件 去另外一台2核4G的机器先安装docker,然后安装后台项目使用的中间件 一.mysql 下载镜像:docker pull mysql:5.7 启动镜像实例:docker run -p 3 ...