Codeforces Aim Tech Round4 (Div2) D
题目链接:
题意:
给你一个严格升序的单链表,但是是用数组来存放的。对于每一个位置来说,你可以知道这个位置的值和下一个的位置。你每一个可以询问一个位置,机器会告诉你这个位置的值,和下一个位置的指针。要你确认大于等于x的值。(询问次数不能超过2000).
题解:
由于给你的可能有5e4个数,除了随机算法,没有一种可以在2000步以内找到小于等于x。
对与随机算法:我们先随机找500个点,找到小于x的点0值中最大的一个。然后暴力询问。小于2000的直接暴力找了。
证明:
我们假设x的位置在Y, 那么在[Y-1500, Y] 将会有一个点被随机到。如果没有一个被随机到,这个概率是:1-1500/5e4 = 0.97。有97%的机率选不到。但是500次随机之后 (0.97)500 = 2.4e- 7。
也就是1e7次的期望值才2。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <cmath> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <stack> 13 #include <set> 14 using namespace std; 15 typedef long long LL; 16 typedef unsigned long long uLL; 17 #define ms(a, b) memset(a, b, sizeof(a)) 18 #define pb push_back 19 #define mp make_pair 20 #define eps 0.0000000001 21 #define IOS ios::sync_with_stdio(0);cin.tie(0); 22 #define random(a, b) rand()*rand()%(b-a+1)+a 23 const LL INF = 0x3f3f3f3f3f3f3f3f; 24 const int inf = 0x3f3f3f3f; 25 const int maxn = 50000+10; 26 const int mod = 1e9+7; 27 bool vis[maxn]; 28 int maxval, pos; 29 int main() { 30 #ifdef LOCAL 31 // freopen("input.txt", "r", stdin); 32 // freopen("output.txt", "w", stdout); 33 #endif 34 35 // IOS 36 srand(time(0)); 37 int n, start, x, val, next; 38 scanf("%d%d%d", &n, &start, &x); 39 if(n<=2000){ 40 int hh = start; 41 while(1){ 42 printf("? %d\n", hh);fflush(stdout); 43 scanf("%d%d", &val, &hh); 44 if(val>=x){ 45 printf("! %d\n", val); 46 return 0; 47 } 48 if(hh==-1){ 49 printf("! -1\n"); 50 return 0; 51 } 52 } 53 } 54 printf("? %d\n", start);fflush(stdout); 55 scanf("%d%d", &maxval, &next); 56 pos = start; 57 for(int i = 1;i<500;i++){ 58 int hh = random(1, n); 59 while(vis[hh]) hh = random(1, n); 60 vis[hh] = 1; 61 printf("? %d\n", hh);fflush(stdout); 62 scanf("%d%d", &val, &next); 63 if(val==x){ 64 printf("! %d\n", x); 65 return 0; 66 } 67 if(val<x){ 68 if(val>maxval){ 69 maxval = val; 70 pos = hh; 71 } 72 } 73 } 74 int hh = pos; 75 for(int i = 0;i<1500;i++){ 76 printf("? %d\n", hh);fflush(stdout); 77 scanf("%d%d", &val, &hh); 78 if(val>=x){ 79 printf("! %d\n", val); 80 return 0; 81 } 82 if(hh==-1){ 83 printf("! -1\n"); 84 return 0; 85 } 86 } 87 return 0; 88 }