当前位置: 首页 > news >正文

CF441D

题目大意

给出一个有n个数的序列

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

题解

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

#include<cstdio>
#include<algorithm>
#include<cstring> 
#define LL long long
using namespace std;
const int maxn=500010,inf=2e9;
int n,top,st[maxn],a[maxn],digit[maxn][32],pre[maxn][32],Pre[maxn],next[maxn][32],Next[maxn],cnt[maxn];
LL ans;
void read(int &k){
    k=0; int f=1; char c=getchar();
    while (c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    while ('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    k*=f;
}
int main(){
    read(n);
    for (int i=1;i<=n;i++){
        read(a[i]);
        for (int x=a[i];x;x>>=1) digit[i][++cnt[i]]=x&1; //处理出a[i]二进制下的每一位 
    }
    ////
    //pre[i][j]表示:在第j位上,第i个数为0时,左边最近的为1的位置;next[i][j]为右边最近的1的位置 
    for (int j=1;j<=30;j++){
        int last=0;
        for (int i=1;i<=n;i++)
        if (!digit[i][j]) pre[i][j]=last;
        else last=i;
    } 
    for (int j=1;j<=30;j++){
        int first=n+1;
        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,32,sizeof(Next)); 
    for (int i=1;i<=n;i++)
    for (int j=1;j<=30;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=1;i<=n;i++){
        for (;top&&a[i]>=a[st[top]];top--){
            ans+=1LL*((i-1)-st[top]+1)*(st[top]-(st[top-1]+1)+1); //以a[st[top]]为最大值的全部区间个数 
            ans-=1LL*(st[top]-max(st[top-1]+1,Pre[st[top]]+1)+1)*(min(i-1,Next[st[top]]-1)-st[top]+1);
            //减去不合法的区间个数 
        }
        st[++top]=i;
    }
    printf("%lld\n",ans);
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/DriverLao/p/7682581.html

相关文章:

  • path--diff
  • 前端基础之html
  • MySQL半同步复制
  • 通过ldap验证svn服务
  • codevs 2620 战壕
  • vue-cli脚手架安装
  • keil 赋值之后再声明变量提示错误error: #268: declaration may not appear after executable statement in block...
  • 正质因数分解
  • 110. Balanced Binary Tree
  • 进程与fork()、wait()、exec函数组
  • Centos_linux系统的区别及实际查看
  • 给Extjs的window弹窗的关闭事件添加验证
  • mysql导入存储过程
  • 系统键盘按钮keyCode大全
  • while(*i++=*t++)都做了些什么。
  • HomeBrew常规使用教程
  • php中curl和soap方式请求服务超时问题
  • Python学习之路16-使用API
  • React-redux的原理以及使用
  • 从tcpdump抓包看TCP/IP协议
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 对象管理器(defineProperty)学习笔记
  • 仿天猫超市收藏抛物线动画工具库
  • 数组的操作
  • 赢得Docker挑战最佳实践
  • 用element的upload组件实现多图片上传和压缩
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • elasticsearch-head插件安装
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • #Lua:Lua调用C++生成的DLL库
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (附源码)php投票系统 毕业设计 121500
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (七)理解angular中的module和injector,即依赖注入
  • (五)关系数据库标准语言SQL
  • (转)Mysql的优化设置
  • (转)创业的注意事项
  • .bashrc在哪里,alias妙用
  • .NET Framework与.NET Framework SDK有什么不同?
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NET/C# 使用反射注册事件
  • .net生成的类,跨工程调用显示注释
  • .NET中winform传递参数至Url并获得返回值或文件
  • .NET中的Exception处理(C#)
  • @EnableWebMvc介绍和使用详细demo
  • [AHOI2009]中国象棋 DP,递推,组合数
  • [C/C++]数据结构 栈和队列()
  • [c]统计数字
  • [HTML]Web前端开发技术29(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页
  • [IE 技巧] 显示/隐藏IE 的菜单/工具栏
  • [LeetCode] NO. 387 First Unique Character in a String
  • [LeetCode]—Copy List with Random Pointer 深度复制带“任意指针”的链表
  • [Linux版本Debian系统]安装cuda 和对应的cudnn以cuda 12.0为例
  • [NOIP2004] 提高组 洛谷P1090 合并果子