Problem Solution

1 solutions

  • 0
    @ 2024-08-17 10:35:22

    ********** editiorial

    lets make another array B[] of length N.
    Elements of B[] will be either 0,1 or 2.

    if the i-th element of the given array is greater than or equal to the previous (i-1 th) element make B[i] = 1

    if the i-th element of the given array is less than or equal to the next (i+1 th) element make B[i] = 1

    if it satisfy both conditions above then make B[i] = 2
    else make B[i] = 0

    Now we can calculate the sum of any range of B[] using segment tree or similar.

    if the sum of any range is 2*range then it means all elements are 2 in the range. which indicates that all the elements in the range are greater than or equal to the previous element and less than or equal to the next element. so the range is definitely sorted.

    A range can still be sorted if the B[l] and/or B[r] is 1. in this case range sum value 2range-1 or 2range-2 can also indicate a sorted range included some conditions. range sum lower than 2*range-2 can be proved as a unsorted range because there must have at least one B[i]==0 or three B[i] that is 1.

    in update operation , updating any index i effects three indexes B[i-1],B[i],B[i+1]

    ************ code

    
    #include<bits/stdc++.h>
    using namespace std;
    int a[200005],b[200005],sgtree[800010];
    
    void build(int node,int start,int end)
    {
        if(start == end)
        {
            sgtree[node] = b[start];
            return;
        }
        int mid = (start+end)/2;
        build(node*2,start,mid);
        build(node*2+1,mid+1,end);
        sgtree[node] = sgtree[node*2] + sgtree[node*2+1];
    }
    
    void update(int node,int start,int end,int ind,int val)
    {
        if(start == end)
        {
            sgtree[node] = val;
            return;
        }
        int mid = (start+end)/2;
        if(ind <= mid) update(node*2,start,mid,ind,val);
        else update(node*2+1,mid+1,end,ind,val);
        sgtree[node] = sgtree[node*2] + sgtree[node*2+1];
    }
    
    int query(int node,int start,int end,int l,int r)
    {
        if(l>end || r<start) return 0;
        if(l<=start && r>=end) return sgtree[node];
        int mid = (start+end)/2;
        int leftsum = query(node*2,start,mid,l,r);
        int rightsum = query(node*2+1,mid+1,end,l,r);
        return leftsum+rightsum;
    }
    
    //ofstream file("output9.txt");
    int main()
    {
        //freopen("input9.txt","r",stdin);
        int n; cin>>n;
        a[0] = 0;
        a[n+1] = 1e9+10;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n;i++) 
        {
            if(a[i] >= a[i-1] && a[i] <= a[i+1]) b[i] = 2;
            else if(a[i] >= a[i-1] || a[i] <= a[i+1]) b[i] = 1;
            else b[i] = 0;
        }
        build(1,1,n);
        int q,type,ind,val,l,r; 
        cin>>q; while(q--)
        {
            cin>>type;
            if(type==1)
            {
                cin >> ind >> val;
                a[ind] = val;
                for(int i=max(1,ind-1); i<= min(n,ind+1); i++)
                {
                    if(a[i] >= a[i-1] && a[i] <= a[i+1]) b[i] = 2;
                    else if(a[i] >= a[i-1] || a[i] <= a[i+1]) b[i] = 1;
                    else b[i] = 0;
                    update(1,1,n,i,b[i]);
                }
            }
            else
            {
                cin>>l>>r;
                int sum , size = (r-l+1);
                if(size==1) {cout<<"YES\n"; continue;}
                sum = query(1,1,n,l,r);
                if(sum == 2*size) cout<<"YES\n";
                else if(sum < (2*size - 2)) cout<<"NO\n";
                else 
                {
                    if(a[l]>a[l+1]) cout<<"NO\n";
                    else if(a[r]<a[r-1]) cout<<"NO\n";
                    else if(b[l]==2 && b[r]==2) cout<<"NO\n";
                    else cout<<"YES\n";
                }
            }
        }
    }
    
  • 1

Information

ID
1085
Difficulty
7
Category
(None)
Tags
(None)
# Submissions
157
Accepted
28
Accepted Ratio
18%
Uploaded By