zoukankan      html  css  js  c++  java
  • QUERY [ 单调栈 ]

    用单调栈预处理出第一个比$a[i]$大/小的数的位置。

    然后枚举左端点$i$,不断拓展右端点$now$,维护$i$~$now$的最大值$ma$、最小值$mi$,$ans$加上$ma$&$mi$乘增加的区间。

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 using namespace std;
     4 const int N=1e5+5;
     5 int n,a[N],Min[N],Max[N],top,s[N];
     6 LL ans;
     7 inline int read() {
     8     int x=0,f=1; char c=getchar();
     9     while(c<'0'||c>'9') {if(c=='-')f=-1; c=getchar();}
    10     while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar();
    11     return x*f;
    12 }
    13 
    14 void prepare() {
    15     for(int i=1;i<=n;i++) {
    16         while(top&&a[i]<a[s[top]]) 
    17          Min[s[top]]=i,top--;
    18         s[++top]=i;
    19         
    20     }
    21     while(top) Min[s[top]]=n+1,top--;
    22     for(int i=1;i<=n;i++) {
    23         while(top&&a[i]>a[s[top]])
    24          Max[s[top]]=i,top--;
    25         s[++top]=i;
    26     }
    27     while(top) Max[s[top]]=n+1,top--;
    28 }
    29 
    30 int main() {
    31     freopen("query.in","r",stdin);
    32     freopen("query.out","w",stdout);
    33     n=read();
    34     for(int i=1;i<=n;i++) a[i]=read();
    35     prepare();
    36     for(int i=1;i<=n;i++) {
    37         int mi=i,ma=i,now=i;
    38         while(now<=n) {
    39             if(Max[ma]<Min[mi]) {
    40                 ans+=(LL)(a[mi]&a[ma])*(Max[ma]-now);
    41                 ma=Max[ma];
    42             }
    43             else {
    44                 ans+=(LL)(a[mi]&a[ma])*(Min[mi]-now);
    45                 mi=Min[mi];
    46             }
    47             now=max(ma,mi);
    48         }
    49     }
    50     printf("%lld",ans);
    51     return 0;
    52 }
  • 相关阅读:
    <转>css选择器基本语法
    Pycharm错误提示
    Python继承Selenium2Library
    对于框架设计的一点总结
    <转>自动化框架设计思想
    svn检出项目报错
    eclipse查看jar包源文件
    plsql连接远程数据库快捷方式
    plsql过期注册
    hql语句cast用法
  • 原文地址:https://www.cnblogs.com/qq8260573/p/11342184.html
Copyright © 2011-2022 走看看