题解:P17234 [Algo Beat Contest 017 C] 交互题
有关
我们考虑两种情况:
先考虑
如果
所以我们得到第一部分思路,如果这个数组里面有
接下来考虑
你考虑记每个
时间复杂度
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,a[200005],mn[200005][20],fi[200005],se[200005];
vector<ll> p[200005];
ll qmn(ll l,ll r){
ll siz=r-l+1;
ll p=log2(siz);
return min(mn[l][p],mn[r-(1<<p)+1][p]);
}
int main(){
cin>>n;
for(ll i=1;i<=n;i++) cin>>a[i],mn[i][0]=a[i],p[a[i]].push_back(i);
for(ll j=1;j<20;j++){
for(ll i=1;i+(1ll<<j)-1<=n;i++){
mn[i][j]=min(mn[i][j-1],mn[i+(1ll<<j-1)][j-1]);
}
}
ll cnt0=0,ans=0;
for(ll i=1;i<=n;i++) cnt0+=(a[i]==0);
if(cnt0){
for(ll i=1;i<=n;i++){
if(a[i]==0) continue;
ll l=i,r=n,res=l;
while(l<=r){
ll md=(l+r)>>1;
if(qmn(i,md)>0) l=md+1,res=md;
else r=md-1;
}
ans+=res-i+1;
}
}
for(ll i=1;i<=n;i++){
if(fi[a[i]]) continue;
fi[a[i]]=i;
}
for(ll i=n;i;i--){
if(se[a[i]]) continue;
se[a[i]]=i;
}
ll l=1e18,r=-1e18;
for(ll i=1;i<=200000;i++){
if(!p[i].size()) continue;
l=min(l,fi[i-1]),r=max(r,se[i-1]);
auto itl=lower_bound(p[i].begin(),p[i].end(),l);
if(itl!=p[i].end()&&*itl<=r) continue;
ll ls=(itl==p[i].begin()?0:*prev(itl));
auto itr=upper_bound(p[i].begin(),p[i].end(),r);
ll rs=(itr==p[i].end()?n+1:(*itr));
ans+=(l-ls)*(rs-r);
}
cout<<ans<<endl;
}