codeforces 876F High Cry (思维,位运算)
来源:互联网 发布:ghostview mac 编辑:程序博客网 时间:2024/06/03 17:07
Disclaimer: there are lots of untranslateable puns in the Russian version of the statement, so there is one more reason for you to learn Russian :)
Rick and Morty like to go to the ridge High Cry for crying loudly — there is an extraordinary echo. Recently they discovered an interesting acoustic characteristic of this ridge: if Rick and Morty begin crying simultaneously from different mountains, their cry would be heard between these mountains up to the height equal the bitwise OR of mountains they've climbed and all the mountains between them.
Bitwise OR is a binary operation which is determined the following way. Consider representation of numbers x and y in binary numeric system (probably with leading zeroes) x = xk... x1x0 and y = yk... y1y0. Then z = x | y is defined following way: z = zk... z1z0, where zi = 1, if xi = 1 or yi = 1, and zi = 0 otherwise. In the other words, digit of bitwise OR of two numbers equals zero if and only if digits at corresponding positions is both numbers equals zero. For example bitwise OR of numbers 10 = 10102 and 9 = 10012 equals 11 = 10112. In programming languages C/C++/Java/Python this operation is defined as «|», and in Pascal as «or».
Help Rick and Morty calculate the number of ways they can select two mountains in such a way that if they start crying from these mountains their cry will be heard above these mountains and all mountains between them. More formally you should find number of pairs l and r (1 ≤ l < r ≤ n) such that bitwise OR of heights of all mountains between l and r (inclusive) is larger than the height of any mountain at this interval.
The first line contains integer n (1 ≤ n ≤ 200 000), the number of mountains in the ridge.
Second line contains n integers ai (0 ≤ ai ≤ 109), the heights of mountains in order they are located in the ridge.
Print the only integer, the number of ways to choose two different mountains.
解题思路:当正面分析不容易得到答案的时候我们很容易想到分析不满足条件的答案个数。
然后我们再来想什么样的情况是不满足条件的呢?
说明这个区间里面所有的数只有最大的那个数所包含的二进制1.
例如一个数 7 二进制 111
那么这个区间里面的数只能是 001 010 100... 而不能是1000.
所以到这里我们可以显而易见的看到我们需要针对每个二进制位进行讨论。
所以我们需要记录每一个二进制位上的1在当前数字前最近的出现位置,还有在当前数字后最近出现的位置。
Trick:需要考虑有相等的数字的情况,为了避免重复计数我们需要维护当前数字上一个出现的位置。
AC代码:
/** @Author: wchhlbt* @Last Modified time: 2017-11-01*/#include <bits/stdc++.h>#define inf 0x3f3f3f3f#define pb push_back#define AA first#define BB second#define ONES(x) __builtin_popcount(x)#define _ << " " <<using namespace std;typedef pair<int, int> P;typedef long long ll ;int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};const double eps =1e-8;const int mod = 1000000007;const double PI = acos(-1.0);inline int read(){ int num; scanf("%d",&num); return num;}const int maxn = 200007;int a[maxn];int l[maxn];//维护每个数字能掌控的左边界int r[maxn];// 右边界int lbit[35];//维护每个位置上的1前一个出现的位置int rbit[35];// 后map<int,int> L;//维护每个数字上一个出现的位置int main(){ int n = read(); for(int i = 1; i<=n; i++) a[i] = read(); memset(lbit,0,sizeof lbit); memset(rbit,inf,sizeof rbit); for(int i = 1; i<=n; i++){ l[i] = L[a[i]]; for(int j = 0; j<32; j++){ if(a[i]&(1<<j)) lbit[j] = i; else l[i] = max(lbit[j],l[i]); } L[a[i]] = i; } for(int i = n; i>=1; i--){ r[i] = n+1; for(int j = 0; j<32; j++){ if(a[i]&(1<<j)) rbit[j] = i; else r[i] = min(rbit[j],r[i]); } } ll ans = 1ll*n*(n+1)/2;//这里会爆int 这里存放的是两个端点可能相同的情况数 for(int i = 1; i<=n; i++){ ll t1,t2; t1 = i-l[i]; t2 = r[i] - i; ans -= (t1*t2); //cout << i _ l[i] _ r[i] _ ans << endl; } cout << ans << endl; return 0;}
- codeforces 876F High Cry (思维,位运算)
- [杂题 位运算] Codeforces #876F. High Cry
- Codeforces 876F High Cry【逆向思维】
- Codeforces 876F High Cry【逆向思维】
- Codeforces Round #441 (Div. 2)F. High Cry 按位考虑 + 思维
- Codeforces #441 Div2 F. High Cry
- Codeforces Round #441 (Div. 2)F. High Cry |区间问题
- Codeforces 875D High Cry
- Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) F. High Cry
- Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) F. High Cry
- Codeforces 875D High Cry rmq+分治
- Codeforces 875D High Cry [枚举+二进制]
- Codeforces 875D High Cry st表+分治
- CF 876F High City 单调栈,枚举,或运算
- codeforces gym 101142 F(思维)
- Codeforces 611F 思维
- CodeForces 865D Buy Low Sell High(思维)
- Codeforces 828 D. High Load 思维+构造
- java设计模式之八:观察者模式
- jzoj5441【NOIP2017提高A组冲刺11.1】序列
- 解读项目中localstorage的使用
- RecyclerView无法按键控制移动的解决办法--给view添加焦点
- CC3200学习之IO口配置
- codeforces 876F High Cry (思维,位运算)
- Java8 Stream的深入学习
- //输入不同对象的姓名、性别、年龄、体重和住址等信息,并输出显示。
- Redis消息的发布/订阅
- 【noip2012】Vigenère 密码
- java反射机制详解
- 设计23式—建造者
- 【vuejs】 模态框组件-confirm或者alert框
- Python_操作列表