CF1479A Searching Local Minimum

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1479A Searching Local Minimum相关的知识,希望对你有一定的参考价值。

CF1479A Searching Local Minimum

题意:

题解:

先说结论:
若l,r满足:

  1. a l − 1 > a l , a r < a r + 1 a_{l-1}>a_{l},a_{r}<a_{r+1} al1>al,ar<ar+1
  2. a l , a l + 1 , . . . . , a r a_{l},a_{l+1},....,a_{r} al,al+1,....,ar互不相同

则一定又一个满足题目条件的k会出现在区间[l,r]中,这就是我们要找的区间
现在我们开始证明:
利用反证法:假设对于任意k∈[l,r]多不满足要求(即 a k < m i n { a i − 1 , a i + 1 } a_{k}<min\\{a_{i-1},a_{i+1}\\} ak<min{ai1,ai+1})
因为 a l − 1 > a l a_{l-1}>a_{l} al1>al,且l不满足要求, a l ! = a l + 1 a_{l}!=a_{l+1} al!=al+1,则一定有 a l > a l + 1 a_{l}>a_{l+1} al>al+1
同理可得: a l + 1 > a l + 2 a_{l+1}>a_{l+2} al+1>al+2, a l + 2 > a l + 3 a_{l+2}>a_{l+3} al+2>al+3, . . . ... ..., a r − 1 > a r a_{r-1}>a_{r} ar1>ar
又因为 a r + 1 > a r a_{r+1}>a_{r} ar+1>ar,则r满足情况,与假设不符

现在开始用这个结论做题, a 0 = a n + 1 = + ∞ a_{0}=a_{n+1}=+∞ a0=an+1=+,说明区间[l,r]就是符合结论的区间,那么答案也肯定在这里面,现在我们要缩小区间范围,可以二分,二分出一个mid,询问mid和mid+1的值
a m i d < a m i d + 1 a_{mid}<a_{mid+1} amid<amid+1,说明[l,mid]也是符合结论的,这样缩小范围
a m i d > a m i d + 1 a_{mid}>a_{mid+1} amid>amid+1,说明[mid+1,r]是符合要求的
这样二分就解决了

代码:

#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{
    x= 0;
    char c= getchar();
    bool flag= 0;
    while (c < '0' || c > '9')
        flag|= (c == '-'), c= getchar();
    while (c >= '0' && c <= '9')
        x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();
    if (flag)
        x= -x;
    read(Ar...);
}
template <typename T> inline void write(T x)
{
    if (x < 0) {
        x= ~(x - 1);
        putchar('-');
    }
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef ONLINE_JUDGE
#else
    startTime = clock ();
    freopen("data.in", "r", stdin);
#endif
}
void Time_test()
{
#ifdef ONLINE_JUDGE
#else
    endTime= clock();
    printf("\\nRun Time:%lfs\\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
const int maxn=1e5+9;
int a[maxn];
int main()
{
    //rd_test();
	int n;
	read(n);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(a[mid]==0){
			printf("? %d\\n",mid);
			fflush(stdout);
			cin>>a[mid];
		}
		if(a[mid+1]==0){
			printf("? %d\\n",mid+1);
			fflush(stdout);
			cin>>a[mid+1];
		}
		if(a[mid]<a[mid+1]){
			r=mid;
		}
		else if(a[mid]>a[mid+1]){
			l=mid+1;
		}
//		printf("");
	}
	printf("! %d\\n",l);
	return 0;
    //Time_test();
}




以上是关于CF1479A Searching Local Minimum的主要内容,如果未能解决你的问题,请参考以下文章

CF 714D Searching Rectangles 交互题 二分

CodeForces - 1480C Searching Local Minimum(交互+二分)

UVA 1597 Searching the Web

[CF930E]/[CF944G]Coins Exhibition

CF398B题解

CF数据结构练习