codeforces E. Monotonic Renumeration(线段树做法)

在这里插入图片描述
蛮水的一道题,就是线段覆盖。
可用线段树维护区间值,若某区间总和为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;
}

猜你喜欢

转载自blog.csdn.net/qq_43781431/article/details/106298453