题目大意

给出一个有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. POJ1808 平方(二次)同余方程

    POJ1808  给定一个方程 x*x==a(mod p) 其中p为质数 判断是否有解 程序中 MOD_sqr()返回整数解 无解返回-1 数学证明略 #include<iostream> ...

  2. G41

    https://downloadcenter.intel.com/zh-cn/product/81517/-G41-

  3. hdu4738(边双连通分量,桥)

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. golang——随机数(math/rand包与crypto/rand包)

    1.math/rand 包 1.1.math/rand 包实现了伪随机数生成器 1.2.主要方法 (1)func Seed(seed int64) 设置随机种子,不设置则默认Seed(1) (2)fu ...

  5. redis存储对象(转)

    原文地址:http://www.cnblogs.com/JKayFeng/p/5911544.html 为什么要实现序列化接口 当一个类实现了Serializable接口(该接口仅为标记接口,不包含任 ...

  6. C语言学习(1)-环境配置

    写在前面的话,该文章是看杨老师的一套视频,所做的一些笔记,边看边写,再此谢谢杨老师. 1.学习C之前需要避免的误区 误区一:C++是C的升级版:C#是C++的升级版 误区二:C/C++就是Visual ...

  7. FCC 基础JavaScript 练习5

    在赌场21点游戏中,玩家可以通过计算牌桌上已经发放的卡牌的高低值来让自己在游戏中保持优势,这就叫21点算法. 根据下面的表格,每张卡牌都分配了一个值.如果卡牌的值大于0,那么玩家应该追加赌注.反之,追 ...

  8. Android PopupWindow使用时注意

    项目中使用PopupWindown出现的坑 1.部分设备,PopWindow在Android4.0后版本,出现NullPointerException调用以下方法可解决, fixPopupWindow ...

  9. Linux 学习(二)

    Linux相关命令 命令 说明 startx 当前用户界面切换至图形界面 init5 切换至另一用户的图形化界面 init3 从图形界面切换回文本界面 pwd 显示当前用户路径 logout 注销 s ...

  10. 配置服务器 Ubuntu 记录+踩坑

    从零开始配置服务器用于ss+站点 1. SS 首先安装pyenv,安装pyenv之前先安装必要环境,具体命令行请见: https://github.com/pyenv/pyenv/wiki/Commo ...