CF1539F Strange Array
题意:给定一个序列,需要求出序列中每个元素的奇怪值。
首先考虑如果区间已经确定,且已经升序排序后如何求距离。
令
显然
同理若
也就是说只要知道
新开一个数组
接下来考虑求
所以只用套区间合并线段树的模板就好。
另外,对于另一种
#include<bits/stdc++.h>
using namespace std;
#define fre(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
#define int long long
#define re register int
#define inf 0x7fffffffffffffff
#define Pair pair<int,int>
inline int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return f==1?x:-x;
}
const int N=2e5+10;
struct Seg{
int l,r,lm,rm,sum;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define lm(x) tree[x].lm
#define rm(x) tree[x].rm
#define sum(x) tree[x].sum
}tree[N<<2];
inline void pushup(int p)
{
sum(p)=sum(p<<1)+sum(p<<1|1);
lm(p)=max(lm(p<<1),sum(p<<1)+lm(p<<1|1));
rm(p)=max(rm(p<<1|1),sum(p<<1|1)+rm(p<<1));
}
void build(int p,int l,int r)
{
l(p)=l;r(p)=r;
if(l==r)return sum(p)=lm(p)=rm(p)=-1,void();
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
pushup(p);
}
void change(int p,int pos,int x)
{
if(l(p)==r(p))return sum(p)=lm(p)=rm(p)=x,void();
int mid=(l(p)+r(p))>>1;
if(pos<=mid)change(p<<1,pos,x);
else change(p<<1|1,pos,x);
pushup(p);
}
Seg query(int p,int l,int r)
{
if(r(p)<l || r<l(p))return {0,0,0,0,0};
if(l<=l(p) && r>=r(p))return tree[p];
Seg a=query(p<<1,l,r),b=query(p<<1|1,l,r);
return {min(a.l,b.l),max(a.r,b.r),max(a.lm,a.sum+b.lm),max(b.rm,b.sum+a.rm),a.sum+b.sum};
}
int n,ans[N];
struct node{int x,id;}a[N];
bool cmp(node a,node b){return a.x<b.x;}
void calc(int flag)
{
build(1,1,n);
for(re i=1;i<=n;++i)
{
int j=i;
while(j<n && a[j+1].x==a[i].x)++j;
for(re k=i;k<=j;++k) change(1,a[k].id,1);
for(re k=i;k<=j;++k)
{
Seg p=query(1,1,a[k].id),q=query(1,a[k].id,n);
ans[a[k].id]=max(ans[a[k].id],p.rm+q.lm-1-!flag);
}
i=j;
}
}
signed main()
{
n=read();
for(re i=1;i<=n;++i)
a[i].x=read(),a[i].id=i;
sort(a+1,a+n+1,cmp);
calc(0);
for(re i=1;i<=n/2;++i) swap(a[i],a[n-i+1]);
for(re i=1;i<=n;++i) a[i].x=-a[i].x;
calc(1);
for(re i=1;i<=n;++i)
printf("%lld ",ans[i]/2);
return 0;
}