zoukankan      html  css  js  c++  java
  • Codeforces Round #441(Div.2) F

    F - High Cry

    题目大意:给你n个数,让你找区间里面所有数或 起来大于区间里面最大数的区间个数。

    思路:反向思维,找出不符合的区间然后用总数减去。我们找出每个数掌控的最左端

    和最右端,一个数的掌控区域为,这个区域里的或 为本身。

    注意两个相同的数有可能掌控区域一样,记得将区域分段。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=2*1e5+5;
    int n,a[N],l[N],r[N];
    map<int,int> mp;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),r[i]=n+1;
        for(int i=0;i<=31;i++)
        {
            int res=0;
            for(int j=1;j<=n;j++)
            {
                if((a[j]>>i)&1) res=j;
                else l[j]=max(l[j],res);
            }
        }
        for(int i=1;i<=n;i++)
        {
            l[i]=max(l[i],mp[a[i]]);
            mp[a[i]]=i;
        }
        for(int i=0;i<=31;i++)
        {
            int res=n+1;
            for(int j=n;j>=1;j--)
            {
                if((a[j]>>i)&1) res=j;
                else r[j]=min(r[j],res);
            }
        }
        ll ans=(ll) n*(n+1)/2;
        for(int i=1;i<=n;i++) ans-=(ll)(i-l[i])*(r[i]-i);
        printf("%I64d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    汉语编程
    第一次作业
    个人总结
    psp表格
    第三次个人作业——用例图设计
    第二次结对作业
    第一次结对作业
    第二次个人编程作业
    第一次编程作业
    第一次博客作业
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7750943.html
Copyright © 2011-2022 走看看