题目大意

给出一个有n个数的序列

求符合 区间各数或起来的数大于区间最大数 的区间的个数

题解

预处理出每个数每一位是0的那位左边最近的1和右边最近的1,用单调栈找出每个最大值所在的区间的左右端点,统计答案即可。

#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
using namespace std;
const int maxn=,inf=2e9;
int n,top,st[maxn],a[maxn],digit[maxn][],pre[maxn][],Pre[maxn],next[maxn][],Next[maxn],cnt[maxn];
LL ans;
void read(int &k){
k=; int f=; char c=getchar();
while (c<''||c>'')c=='-'&&(f=-),c=getchar();
while (''<=c&&c<='')k=k*+c-'',c=getchar();
k*=f;
}
int main(){
read(n);
for (int i=;i<=n;i++){
read(a[i]);
for (int x=a[i];x;x>>=) digit[i][++cnt[i]]=x&; //处理出a[i]二进制下的每一位
}
////////////////////////////////////////////
//pre[i][j]表示:在第j位上,第i个数为0时,左边最近的为1的位置;next[i][j]为右边最近的1的位置
for (int j=;j<=;j++){
int last=;
for (int i=;i<=n;i++)
if (!digit[i][j]) pre[i][j]=last;
else last=i;
}
for (int j=;j<=;j++){
int first=n+;
for (int i=n;i;i--)
if (!digit[i][j]) next[i][j]=first;
else first=i;
}
////////////////////////////////////////////
//对于一个数,不合法区间的左端点为其各个为0数位上,左边最近的1的位置的最大值
//右端点为其各个为0数位上,右边最近的1的位置的最小值
//即对于maxnumber,它的每个为0位,不合法区间内的其他数的这一位都为0,这样区间or起来之后等于maxnumber
memset(Next,,sizeof(Next));
for (int i=;i<=n;i++)
for (int j=;j<=;j++) if (!digit[i][j])
Pre[i]=max(Pre[i],pre[i][j]),Next[i]=min(Next[i],next[i][j]);
//////////////////////////////////////////// 单调栈维护以a[i]为最大值的区间的左右端点
a[++n]=inf;
for (int i=;i<=n;i++){
for (;top&&a[i]>=a[st[top]];top--){
ans+=1LL*((i-)-st[top]+)*(st[top]-(st[top-]+)+); //以a[st[top]]为最大值的全部区间个数
ans-=1LL*(st[top]-max(st[top-]+,Pre[st[top]]+)+)*(min(i-,Next[st[top]]-)-st[top]+);
//减去不合法的区间个数
}
st[++top]=i;
}
printf("%lld\n",ans);
return ;
}

CF441D的更多相关文章

随机推荐

  1. CF 600 E Lomsat gelral —— 树上启发式合并

    题目:http://codeforces.com/contest/600/problem/E 看博客:https://blog.csdn.net/blue_kid/article/details/82 ...

  2. Permutations II 典型去重

    https://leetcode.com/problems/permutations-ii/ Given a collection of numbers that might contain dupl ...

  3. redis 缓存应用

    第1章 部署与安装 wget http://download.redis.io/releases/redis-3.2.10.tar.gz tar xf redis-3.2.10.tar.gz cd r ...

  4. 6.13---shiro

  5. Android 新闻app的顶部导航栏,怎么实现动态加载?

    TabLayout + viewpager 其中viewpager的适配器要继承FragmentPagerAdapter,要实现动态更新,最主要的是适配器的写法,要在数据发生变化之后清除Fragmen ...

  6. 联想 Vibe Shot(Z90-3) 免recovery 获取ROOT权限 救砖 VIBEUI V3.1_1625

    >>>重点介绍<<< 第一:本刷机包可卡刷可线刷,刷机包比较大的原因是采用同时兼容卡刷和线刷的格式,所以比较大第二:[卡刷方法]卡刷不要解压刷机包,直接传入手机后用 ...

  7. 读《An Adaptable and Extensible Geometry Kernel》

    读<An Adaptable and Extensible Geometry Kernel> 利用Curiously Recurring Template Pattern替代虚函数 详细内 ...

  8. RPC——笔记

    整理的笔记来源:https://mp.weixin.qq.com/s/JkXrPcuKtE2qYgmDcH2uww RPC(远程过程调用): RPC是:一个计算机通信协议. 调用过程:计算机 A 上的 ...

  9. 【转】非常好的Java反射例子

    转自 http://www.douban.com/note/306848299/ 原文: 1.Java反射的概念 反射含义:可以获取正在运行的Java对象. 2.Java反射的功能 1)可以判断运行时 ...

  10. Java学习2_一些基础2_字符串_16.5.5

    接上一次的博客. 不可变字符串: Java中String类没有提供用于修改字符串的方法.如果想将greeting中的“Hello”改为“Help!”需要先提取所需要的的字符,然后再拼接.即 greet ...