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种,每种 ...
随机推荐
- 喜欢去知乎炸鱼?用python吧
知乎高赞贴: 有一双大长腿是什么体验? 有一副迷人的身材是什么体验? 别用手机费劲的翻了,python帮你一臂之力 import re import requests import os import ...
- ROS-RouterOS KVM 安装 OpenWrt 旁路使用
原文: http://bbs.routerclub.com/thread-104864-1-1.html 这里所讲是X86架构的RouteROS的KVM虚拟机,其实RouterOS的KVM很早就有,大 ...
- Golang 基础语法介绍及对比(二)
传值与传参 Golong func main() { a := fmt.Println("a = ", a) // 应该输出 "a= 3" a1 := add1 ...
- LeetCode 75. Sort Colors (颜色分类):三路快排
Given an array with n objects colored red, white or blue, sort them in-place so that objects of the ...
- Java中HashMap和TreeMap的区别
什么是Map集合在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.这就是我们平时说的键值对. HashMap ...
- jquery easyui datagrid 加载保存好的自定义设置的列属性
直接附上源代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...
- Installing Google Chrome in Linux(RedHat Enterprise Linux 7)
# wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm # yum -y install r ...
- DFRobot模块物联网演示项目整合
简介 本文是此次物联网项目的终结篇.本文将演示如何整合之前的文章中的模块和代码,来简单的完成一个物联网项目.最终的实现效果是:利用Iphone手机上的MQTTool App,来获取DHT11的温湿度数 ...
- scala中的Option
Scala中Option是用来表示一个可选类型 什么是可选? --> 主要是指 有值(Some) 和 无值(None)-->Some和None是Option的子类 val myMap:Ma ...
- Turbo码基本框架
1. 基本原理 1.1 定义 1.2 分量码设计 2. 编码方法 2.1 交织器的设计 2.2 分量编码器 2.3 删余矩阵及复用 3. 译码方法和算法 3.1 迭代译码 3.2 MAP类算法 3.3 ...