noip模拟赛 区间
2017-11-02 21:57
288 查看
分析:要遍历所有的区间,肯定是枚举左端点,然后再枚举右端点.关键是怎么高效地求区间&,|,一般而言是用前缀和的,但是&,|不满足区间可减性,所以可以考虑线段树?这道题不带修改操作,用线段树太浪费了,那么可以用ST表来维护.
查询做到O(1)了,但是怎么快速枚举区间呢?枚举左端点和右端点肯定只能选择一个优化,优化枚举右端点的循环.观察数据范围,100000,很容易想到二分.可以每次固定左端点,然后二分右端点的位置.因为&操作随着区间数的增加而答案减少,|是增加,都满足单调性,所以求满足两个条件的区间的交,统计一下区间的元素个数有多少个就可以了.
#include <cstdio> #include <cmath> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const long long inf = 1LL << 60, mod = 1e9 + 7; typedef long long ll; ll n, a, b, c, d, f1[100010][22], f2[100010][22], s[100010], ans; void init() { for (int j = 1; j <= 21; j++) for (int i = 1; i + (1 << j) - 1 <= n; i++) { f1[i][j] = f1[i][j - 1] & f1[i + (1 << (j - 1))][j - 1]; f2[i][j] = f2[i][j - 1] | f2[i + (1 << (j - 1))][j - 1]; } } ll query(ll l, ll r,ll op) { ll k = (ll)((log(r - l + 1)) / log(2.0)); if (op == 1) return f1[l][k] & f1[r - (1 << k) + 1][k]; else return f2[l][k] | f2[r - (1 << k) + 1][k]; } int main() { scanf("%lld%lld%lld%lld%lld", &n, &a, &b, &c, &d); for (int i = 1; i <= n; i++) { scanf("%lld", &s[i]); f1[i][0] = f2[i][0] = s[i]; } init(); for (int i = 1; i <= n; i++) { ll l = i, r = n, temp1 = inf, temp2 = -inf, temp3 = inf, temp4 = -inf; while (l <= r) { ll mid = (l + r) >> 1; if (query(i, mid,1) >= a) { l = mid + 1; temp2 = mid; } else r = mid - 1; } l = i, r = n; while (l <= r) { ll mid = (l + r) >> 1; if (query(i, mid, 1) <= b) { r = mid - 1; temp1 = mid; } else l = mid + 1; } l = i, r = n; while (l <= r) { ll mid = (l + r) >> 1; if (query(i, mid, 2) >= c) { r = mid - 1; temp3 = mid; } else l = mid + 1; } l = i, r = n; while (l <= r) { ll mid = (l + r) >> 1; if (query(i, mid, 2) <= d) { l = mid + 1; temp4 = mid; } else r = mid - 1; } ll ll = max(temp1, temp3), rr = min(temp2, temp4); ans += max((long long)0, rr - ll + 1); ans %= mod; } printf("%lld\n", ans); return 0; }
相关文章推荐
- 【NOIP 模拟赛】区间第K大(kth) 乱搞
- [noip2011模拟赛]区间问题
- JZOJ1489.2017.04.02【NOIP 普及组】模拟赛C组 T1区间
- noip模拟赛 第k大区间
- 【NOIP模拟赛】公主的朋友 区间染色问题
- 2017.04.02【NOIP 普及组】模拟赛C组 T1:区间
- 【NOIP模拟赛】工资
- 【NOIP 模拟题】[山东多校联合模拟赛 day1 T2] 祖先(dp)
- [noip模拟赛]求和(快速幂)
- noip模拟赛 hungary
- noip模拟赛 序
- 2016.09.03【初中部 NOIP提高组 】模拟赛A总结
- noip模拟赛 道路分组
- 洛谷noip 模拟赛 day1 T1
- EZOI [NOIP模拟赛][线段树]
- NOIP欢乐模拟赛 T2 解题报告
- 动态规划 - 区间DP - NOIP 乘积最大
- 2017.08.15【NOIP提高组】模拟赛B组总结
- 2017.08.17【NOIP提高组】模拟赛B组总结
- NOIP模拟赛-旅行者问题 解题报告