1 条题解

  • -3
    @ 2026-1-19 22:14:14

    思路:二分答案+单调队列 Code:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=1e5+5;
    int n,k;
    int h[N],q1[N],p1[N],q2[N],p2[N];
    vector<pair<int,int>> v;
    vector<int> query_min(int k)
    {
    	int head=1,tail=0;
    	vector<int> ans;
    	for(int i=1; i<=n; ++i)
    	{
    		while(head<=tail && q1[tail]>=h[i])
    		{
    			--tail;
    		}
    		++tail;
    		q1[tail]=h[i];
    		p1[tail]=i;
    		while(p1[head]<=i-k)
    		{
    			++head;
    		}
    		if(i>=k)
    		{
    			ans.push_back(q1[head]);
    		}
    	}
    	return ans;
    }
    vector<int> query_max(int k)
    {
    	int head=1,tail=0;
    	vector<int> ans;
    	for(int i=1; i<=n; ++i)
    	{
    		while(head<=tail && q2[tail]<=h[i])
    		{
    			--tail;
    		}
    		++tail;
    		q2[tail]=h[i];
    		p2[tail]=i;
    		while(p2[head]<=i-k)
    		{
    			++head;
    		}
    		if(i>=k)
    		{
    			ans.push_back(q2[head]);
    		}
    	}
    	return ans;
    }
    bool check1(int mid)
    {
    	memset(p1,0,sizeof p1);
    	memset(p2,0,sizeof p2);
    	memset(q1,0,sizeof q1);
    	memset(q2,0,sizeof q2);
    	bool flag=0;
    	vector<int> v1=query_max(mid);
    	vector<int> v2=query_min(mid);
    	for(int i=0; i<v1.size(); ++i)
    	{
    		if(v1[i]-v2[i]<=k)
    		{
    			flag=1;
    			break;
    		}
    	}
    	return flag;
    }
    bool check2(int mid)
    {
    	memset(p1,0,sizeof p1);
    	memset(p2,0,sizeof p2);
    	memset(q1,0,sizeof q1);
    	memset(q2,0,sizeof q2);
    	bool flag=0;
    	vector<int> v1=query_max(mid);
    	vector<int> v2=query_min(mid);
    	for(int i=0; i<v1.size(); ++i)
    	{
    		if(v1[i]-v2[i]<=k)
    		{
    			flag=1;
    			v.push_back({i+1,i+mid});
    		}
    	}
    	return flag;
    }
    signed main()
    {
    	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    	cin>>n>>k;
    	for(int i=1; i<=n; ++i)
    	{
    		cin>>h[i];
    	}
    	int l=1,r=1e18;
    	while(l<=r)
    	{
    		int mid=(l+r)/2;
    		if(check1(mid))
    		{
    			l=mid+1;
    		}
    		else
    		{
    			r=mid-1;
    		}
    	}
    	check2(r);
    	cout<<r<<' '<<v.size()<<'\n';
    	for(int i=0; i<v.size(); ++i)
    	{
    		cout<<v[i].first<<' '<<v[i].second<<'\n';
    	}
    	return 0;
    }
    

    信息

    ID
    13845
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者