蛮水的一道题,就是线段覆盖。
可用线段树维护区间值,若某区间总和为0,则说明该区间任何一个点都没有被覆盖
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct qq
{
ll w,ip;
}q[200005];
ll a[200005],d[200005],mod=998244353;
struct node
{
ll l,r,pre,add;
}sum[800005];
bool cmp(qq a,qq b)
{
if(a.w<b.w)
{
return 1;}
if(a.w==b.w)
{
if(a.ip<b.ip)
{
return 1;}
return 0;
}
return 0;
}
void build(ll l,ll r,ll os)
{
sum[os].l=l;
sum[os].r=r;
if(l==r)
{
sum[os].pre=0;
return;}
ll mid=(l+r)/2;
build(l,mid,os*2);
build(mid+1,r,os*2+1);
sum[os].pre=sum[os*2].pre+sum[os*2+1].pre;
}
void spread(ll os)
{
if(sum[os].add)
{
sum[os*2].pre+=(sum[os].add*(sum[os*2].r-sum[os*2].l+1));
sum[os*2+1].pre+=(sum[os].add*(sum[os*2+1].r-sum[os*2+1].l+1));
sum[os*2].add+=sum[os].add;
sum[os*2+1].add+=sum[os].add;
sum[os].add=0;
}
}
void change(ll x,ll y,ll os)
{
if(x<=sum[os].l&&y>=sum[os].r)
{
sum[os].pre+=(sum[os].r-sum[os].l+1);
sum[os].add+=1;
return;
}
spread(os);
ll mid=(sum[os].l+sum[os].r)/2;
if(x<=mid)
{
change(x,y,os*2);}
if(y>mid)
{
change(x,y,os*2+1);}
sum[os].pre=sum[os*2].pre+sum[os*2+1].pre;
}
ll query(ll x,ll y,ll os)
{
if(x<=sum[os].l&&y>=sum[os].r)
{
return sum[os].pre;}
spread(os);
ll mid=(sum[os].l+sum[os].r)/2;
ll ans=0;
if(x<=mid)
{
ans+=query(x,y,os*2);}
if(y>mid)
{
ans+=query(x,y,os*2+1);}
return ans;
}
int main()
{
ll n,ans=1;
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);q[i].w=a[i];q[i].ip=i;}
sort(q+1,q+1+n,cmp);
build(1,n,1);
for(int i=1;i<=n;i++)
{
d[i]=q[i].w;}
ll p1=lower_bound(d+1,d+1+n,a[1])-d;
ll p2=upper_bound(d+1,d+1+n,a[1])-d;
/
ll x=q[p1].ip,y=q[p2-1].ip;
change(x,y,1);
for(int i=2;i<=n;i++)
{
p1=lower_bound(d+1,d+1+n,a[i])-d;
p2=upper_bound(d+1,d+1+n,a[i])-d;
x=q[p1].ip;y=q[p2-1].ip;
if(query(x,y,1)==0)
{
change(x,y,1);
ans=(ans*2)%mod;}
else
{
change(x,y,1);}
}
printf("%lld\n",ans);
return 0;
}