APIO2016 Gap

似乎是个大水题,多数的题解是暴力分块区间的做法。

这里介绍一种略微优秀一点的做法,截至发表时在UOJ上用时rk1,询问次数挺少说不定也有rk1

首先用O(n+1)的代价找到最大最小

考虑答案下限显然有max((r - l)/(n-1) , 1)

我们考虑动态分块,每次划分的块是当前的ans,显然在这个区间里面的数都没有什么卵用

不断更新当前的区间L , R , 同时找出当前区间的mn和mx的时候更新答案

维护上一次的找的的最大/最小

在跑的时候顺便动态更新块的大小,因为显然如果一个块啥都没有答案肯定可以更新变大

注意细节问题

我相信你们都没听懂还是看代码吧

 1 #include"gap.h"
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 long long num[100005];
 5 long long brout(int T,int n)
 6 {
 7     int w = n;
 8     long long l = 0 , r = 1e18;
 9     int L = 1 , R = n;
10     num[0] = num[n + 1] = 1e18;
11     long long mn , mx;
12     long long ans = 0;
13     while(w && (r - l) > ans && L <= R){
14         MinMax(l , r , &mn , &mx);
15         if(mn == mx){num[L] = mn;ans = max(ans , max(num[R + 1] - mn , mn - num[L - 1]));break;}
16         num[L] = mn , num[R] = mx;
17         l = mn + 1;
18         r = mx - 1;
19         if(L > 1){ ans = max(ans , max(num[L] - num[L - 1] , num[R + 1] - num[R]));}
20         if(L == R - 1) ans = max(ans , num[R] - num[L]);
21         L++ , R--;
22     }
23     return ans;
24 }
25 long long findGap(int T,int n)
26 {
27     if(T == 1) return brout(T , n);
28     long long l = 0 , r = 1e18;
29     num[0] = num[n + 1] = 1e18;
30     long long mn , mx , mn2 , mx2;
31     long long ans = 1 , LL , RL;
32     MinMax(0 , 1e18 , &l , &r);
33     if(n == 2) return r - l;
34     LL = l , RL = r;
35     ans = max((r - l) / (n - 1), 1LL);
36     while((r - l) > ans){
37         bool f = 0;
38         mx = -1;
39         do{
40             if(mx != -1) {LL = mx;}
41             if(f) l = l + ans;
42             if(r - l <= ans) break;
43             f = 1;
44             ans = max(ans , l - LL);
45             MinMax(l + 1 , min(l + ans , r - 1), &mn , &mx);
46         }while((mx == -1 || (mn - LL <= ans)) && (r - l > ans));
47         l = l + ans;
48         if(mn != -1) {ans = max(ans , mn - LL);LL = mx;}
49         if(r - l <= ans) break;
50         mn = -1;f = 0;
51         do{
52             if(mn != -1) {RL = mn;}
53             if(f) r = r - ans;
54             if(r - l <= ans) break;
55             f = 1;
56             ans = max(ans , RL - r);
57             MinMax(max(r - ans , l + 1) , r - 1 , &mn , &mx);
58         }while((mn == -1 || (RL - mx <= ans)) && (r - l > ans));
59         r = r - ans;
60         if(mx != -1) {ans = max(ans , RL - mx);RL = mn;}
61         if(r - l <= ans) break;
62     }
63     l = LL , r = RL;
64     if(l < r - 1){
65         MinMax(l + 1 , r - 1 , &mn , &mx);
66         if(mn != -1) ans = max(ans , max(mn - LL , RL - mx));
67         else ans = max(ans , RL - LL);
68     }
69     else ans = max(ans , RL - LL);
70     return ans;
71 }
View Code

猜你喜欢

转载自www.cnblogs.com/RDDCCD/p/9191609.html
GAP
GAP