CF1237D Balanced Playlist

思路:
假设从第i首歌开始听,结束位置为j,那么从第i+1首歌开始听,结束位置一定不早于j。可以用反证法证明。想到这一点,就不难解决了。

实现:

 1 #include 
 2 using namespace std;
 3 const int INF = 0x3f3f3f3f;
 4 const int N = 300005;
 5 int a[N], st[N][20];
 6 int log2(int x)
 7 {
 8     int res = -1;
 9     while (x) { x >>= 1; res++; }
10     return res;
11 }
12 void init(int n)
13 {
14     for (int i = 0; i < n; i++) st[i][0] = a[i];
15     for (int j = 1; (1 << j) < n; j++)
16     {
17         for (int i = 0; i + (1 << j) - 1 < n; i++)
18         {
19             st[i][j] = max(st[i][j - 1], st[i + (1 << j - 1)][j - 1]);
20         }
21     }
22 }
23 int get_max(int l, int r)
24 {
25     if (l > r) return -INF;
26     int p = log2(r - l + 1);
27     return max(st[l][p], st[r - (1 << p) + 1][p]);
28 }
29 int main()
30 {
31     int n;
32     while (cin >> n)
33     {
34         int minn = INF, maxn = -INF;
35         for (int i = 0; i < n; i++)
36         {
37             cin >> a[i]; a[i + n] = a[i + 2 * n] = a[i];
38             minn = min(a[i], minn);
39             maxn = max(a[i], maxn);
40         }
41         init(3 * n);
42         vector<int> res(n, -1);
43         if (maxn <= minn * 2)
44         {
45             for (auto it: res) cout << it << " ";
46             cout << endl; continue;
47         }
48         int cur = 0;
49         for (int i = 0; i < n; i++)
50         {
51             cur = max(cur, i + 1);
52             int maxn = get_max(i, cur);
53             while (cur < 3 * n && a[cur] * 2 >= maxn)
54             {
55                 maxn = max(maxn, a[cur]); cur++;
56             }
57             res[i] = cur - i;
58         }
59         for (auto it: res) cout << it << " ";
60         cout << endl;
61     }
62     return 0;
63 }

你可能感兴趣的:(CF1237D Balanced Playlist)