• [loj3697]262144 Revisited


    记$cnt_{v}$表示答案$\ge v$的区间数量,则问题即求$\sum_{v\ge 1}cnt_{v}$

    记$f_{l}$表示最大的右端点$r$满足区间$[l,r)$的答案$<v$,则$cnt_{v}={n+1\choose 2}-\sum_{l=1}^{n}(f_{l}-l)$

    初始$v=1$且$f_{l}=l$,当$v\rightarrow v+1$时转移即$f'_{l}=\begin{cases}l+1&a_{l}=v\\f_{f_{l}}&a_{l}\ne v\end{cases}$,时间复杂度为$o(n^{2})$

    结论1:对于所有$v$,答案为$v$的极长区间数之和为$o(n\log n)$

    记$f_{n}$为$n$时的答案,归纳证明$f_{n}\le o(\log n!)\le o(n\log n)$

    设$a_{p}$为最大值,则$f_{n}=f_{p-1}+f_{n-p}+$包含$p$的极长区间数

    在确定左端点后$l$后,显然$[l,n]$的答案$\le [l,p]$的答案$+o(\log \frac{n}{p})$,因此至多$o(\log \frac{n}{p})$个极长区间​

    对于所有$o(p)$个左端点,包含$p$的极长区间数$\le o(p\log \frac{n}{p})\le o(\sum_{i=0}^{p-1}\log \frac{n-i}{p-i})=o(\log\frac{n!}{p!(n-p)!})$

    代入原式显然成立,即得证

    结合上述结论,考虑以下优化——

    优化1:仅维护所有极长且非空的区间$[l,f_{l})$,由于$f$单调不降,条件即$\max(l,f_{l-1})<f_{l}$

    在此基础上,转移分为两步:

    1.将区间$[l,f_{l})$替换为$[l,f'_{l})$,其中$f_{f_{l}}$可以双指针求出(注意判断$[l,f'_{l})$是否极长)

    2.对于$a_{l}=v$的位置,新增区间$[l,l+1)$,可以用归并排序与前者合并

    优化2:若$\min(a_{l-1},a_{f_{l}})\ge v$,则$f'_{l}=f_{l}$(转移不影响),将其单独存储在$l$和$f_{l}$上

    显然每一个位置至多存储一个,并在$a_{l}=v$时将$l$和$l+1$上存储的区间重新维护即可

    结论2:上述做法的时间复杂度为$o(n\log n)$

    不难发现,所有维护/存储(包括优化2)的区间$[l,f_{l})$即答案$<v$的极长区间

    关于转移的第1步,对$[l,f'_{l})$是否极长分类讨论:

    1.若不极长,即使得区间个数-1,可以均摊到加入区间时

    2.若极长,结合$\min(a_{l-1},a_{f_{l}})<v$,在$[l-1,f_{l})$和$[l,f_{l}]$中总有一个答案$\le v$

    两者均包含$[l,f_{l})$,因此$[l,f'_{l})$极长的必要条件为$f_{l}<f'_{l}$,进而$[l,f'_{l})$的答案恰为$v$(结合$f$定义)

    进一步的,$[l,f'_{l})$必然是答案为$v$的极长区间,根据结论1总复杂度至多为$o(n\log n)$

    另外,转移的第2步和优化2存储的复杂度显然均为$o(n)$,即得证

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 300000
     4 #define M 1000100
     5 #define ll long long
     6 #define pii pair<int,int>
     7 #define mp make_pair
     8 #define fi first
     9 #define se second
    10 int n,a[N];ll sum,ans;pii f0[N];
    11 vector<int>v[M];vector<pii>g,f;
    12 void add(pii k){
    13     f0[k.fi]=f0[k.se]=k;
    14     sum+=(ll)(k.se-k.fi)*(k.se-k.fi+1)/2;
    15 }
    16 void dec(pii k){
    17     f0[k.fi]=f0[k.se]=mp(0,0);
    18     sum-=(ll)(k.se-k.fi)*(k.se-k.fi+1)/2;
    19 }
    20 int main(){
    21     scanf("%d",&n);
    22     for(int i=1;i<=n;i++){
    23         scanf("%d",&a[i]);
    24         v[a[i]].push_back(i);
    25     }
    26     for(int i=1;i<M;i++){
    27         g.clear(),ans+=(ll)n*(n+1)/2-sum;
    28         for(int x=0;x<f.size();x++){
    29             int s=min(f[x].se,(x+1<f.size() ? f[x+1].fi-1 : n));
    30             ans-=(ll)((f[x].se-s)+(f[x].se-f[x].fi))*(s-f[x].fi+1)/2;
    31         }
    32         for(int x=0,y=0;x<f.size();x++){
    33             while ((y+1<f.size())&&(f[y+1].fi<=f[x].se))y++;
    34             if ((g.empty())||(g.back().se<f[y].se))g.push_back(mp(f[x].fi,f[y].se));
    35         }
    36         f.clear();
    37         for(int x=0,y=0;x<=g.size();x++){
    38             int s=(x<g.size() ? g[x].fi : n+1);
    39             while ((y<v[i].size())&&(v[i][y]<s)){
    40                 int k=v[i][y];
    41                 if (f0[k].fi)f.push_back(f0[k]),dec(f0[k]);
    42                 f.push_back(mp(k,k+1));
    43                 if (f0[k+1].fi)f.push_back(f0[k+1]),dec(f0[k+1]);
    44                 y++;
    45             }
    46             if (x<g.size()){
    47                 bool flag=0;
    48                 if ((g[x].fi>1)&&(a[g[x].fi-1]<=i))flag=1;
    49                 if ((g[x].se<=n)&&(a[g[x].se]<=i))flag=1;
    50                 if (!flag)add(g[x]);
    51                 else f.push_back(g[x]);
    52             }
    53         }
    54     }
    55     printf("%lld\n",ans);
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    使用libmap
    仿真 vcs/ncverilog
    git——git不常见指令记录
    Mac更换鼠标指针样式_ANI、CUR文件解析
    油猴脚本——CSDN防复制破解
    解决Establishing SSL connection without server‘s identity verification is not recommended.
    IDEA激活 试用30天 自动激活
    IDEA Plugins:Free Mybatis plugin(Mapper跳转XML)安装及使用
    Springboot异常汇总
    springbootdemo
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/16153648.html
Copyright © 2020-2023  润新知