zoukankan      html  css  js  c++  java
  • CF875D High Cry

    传送门

    题目要求合法的区间个数,这里考虑用总区间个数减去不合法的个数

    假设某个数为区间最大值,那么包含这个数的最长区间内,所有数小于他并且所有数没有这个最大值没有的二进制位,可以按位考虑每个数(i)(j)这一位上向左和向右第一个二进制位为1的位置,分别记为(l_{i,j},r_{i,j}),然后每个数再考虑所有二进制为0的位上的(l_{i,j},r_{i,j})区间的交集,左右端点为(ll,rr),那个这一位对答案加上((i-ll)*(rr-j))

    要注意,前面可能有值相同的数,导致这次计算的(ll)包含了上次计算过的区间,这时候要让(ll)(a_i)上次出现的位置取max

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define db double
    #define eps (1e-8)
    
    using namespace std;
    const int N=200000+10;
    il LL rd()
    {
        re LL x=0,w=1;re char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int n,a[N],l[N][33],r[N][33];
    LL ans;
    map<int,int> la;
    
    int main()
    {
      n=rd();
      for(int i=1;i<=n;i++) a[i]=rd();
      for(int i=1;i<=n;i++)
        for(int j=0;j<=32;j++)
          l[i][j]=(a[i]&(1<<j))?i:l[i-1][j];
      for(int j=0;j<=32;j++) r[n+1][j]=n+1;
      for(int i=n;i>=1;i--)
        for(int j=0;j<=32;j++)
          r[i][j]=(a[i]&(1<<j))?i:r[i+1][j];
      for(LL i=1;i<=n;i++)
        {
          LL ll=0,rr=n+1;
          for(int j=0;j<=32;j++)
            {
              if(a[i]&(1<<j)) continue;
              ll=max(ll,l[i][j]),rr=min(rr,r[i][j]);
            }
          ll=max(ll,la[a[i]]);
          la[a[i]]=i;
          ans+=(i-ll)*(rr-i);
        }
      printf("%lld
    ",1ll*n*(n+1)/2-ans);
      return 0;
    }
    
    
  • 相关阅读:
    web fileReader API
    placeholer 改变颜色
    在选择标签中遇到的问题
    选择标签
    cesh
    sui 无限下拉分页
    调用百度地图 API 移动地图时 maker 始终在地图中间 并根据maker 经纬度 返回地址
    两种轮播图实现方式
    CSS多行文本溢出省略显示
    从Python看Web架构的发展
  • 原文地址:https://www.cnblogs.com/smyjr/p/9691022.html
Copyright © 2011-2022 走看看