This is a very easy problem ,
we have to use range max and range min query ...
for any ith index we initially suppose that it will form ans till n-1 ,
now we find range max and min in the range i to mid ( mid =l+r/2) and find mid if its diff is <k than we try to shift L so that we can cover more elements from i else we shift R
--------------------------------------code----------------------------------------------------------------------
#include<bits/stdc++.h> using namespace std; typedef long long int lli; struct st { lli maxi; lli mini; lli sum; } seg[1000000]; int arr[1000000]; void build(int idx,int start,int end) { if(start>end) return; else if(start==end) { //cout<<" set base "<<endl; seg[idx].maxi=arr[start]; seg[idx].mini=arr[start]; seg[idx].sum=arr[start]; return ; } int mid=(start+end)/2; build(2*idx,start,mid); build(2*idx+1,mid+1,end); seg[idx].maxi=max(seg[2*idx].maxi,seg[2*idx+1].maxi); seg[idx].mini=min(seg[2*idx].mini,seg[2*idx+1].mini); seg[idx].sum=seg[2*idx].sum+seg[2*idx+1].sum; } st qry(int idx,int start,int end,int qs,int qe) { if(start>end || qs>end || qe<start) { st temp; temp.maxi=INT_MIN; temp.mini=INT_MAX; temp.sum=0; return temp; } else if(start>=qs && end<=qe) { return seg[idx]; } int mid=(start+end)/2; st l=qry(2*idx,start,mid,qs,qe); st r=qry(2*idx+1,mid+1,end,qs,qe); st ret; ret.maxi=max(l.maxi,r.maxi); ret.mini=min(l.mini,r.mini); ret.sum=l.sum+r.sum; return ret; } int main() { int n,m; cin>>n>>m; for(int i=0;i<n;i++) { scanf("%d",&arr[i]); } build(1,0,n-1); int ans=1; for(int i=0;i<n;i++) { int l=i; int r=n-1; int op=17; int ff=0; while(l<=r) { if(l==r) ff=1; int mid=(l+r)/2; st temp=qry(1,0,n-1,i,mid); // cout<<" range "<<i<<" to "<<mid<<" max "<<temp.maxi<<" min "<<temp.mini<<" "<<temp.sum<<endl; if(temp.maxi-temp.mini<=m) { ans=max(ans,mid-i+1); l=mid+1; } else { r=mid; } if(ff==1) break; } // cout<<i<<" "<<ans<<endl; } int count=0; vector<pair<int ,int> > v; for(int i=0;i<n;i++) { int l=i; int r=n-1; int op=17; int anss=1; int rr=i; int ff=0; while(l<=r) { if(l==r) ff=1; int mid=(l+r)/2; st temp=qry(1,0,n-1,i,mid); //cout<<" range "<<i<<" to "<<mid<<" max "<<temp.maxi<<" min "<<temp.mini<<" "<<temp.sum<<endl; if(temp.maxi-temp.mini<=m) { anss=max(anss,mid-i+1); rr=max(rr,mid); l=mid+1; } else { r=mid; } if(ff==1) break; } if(anss==ans) { v.push_back({i+1,rr+1}); } // cout<<i<<" "<<ans<<endl; } cout<<ans<<" "<<v.size()<<endl ; int siz=v.size(); for(int i=0;i<siz;i++) printf("%d %d\n",v[i].first ,v[i].second); }
No comments:
Post a Comment