【bzoj4444】[Scoi2015]国旗计划 倍增
生活随笔
收集整理的這篇文章主要介紹了
【bzoj4444】[Scoi2015]国旗计划 倍增
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
給出一個圈和若干段,問:對于所有的 $i$ ,選擇第 $i$ 段的情況下,最少需要選擇多少段(包括第 $i$ 段)能夠覆蓋整個圈?輸入
第1行,包含2個正整數N,M,分別表示邊防戰士數量和邊防站數量。 隨后n行,每行包含2個正整數。其中第i行包含的兩個正整數Ci、Di分別表示i號邊防戰士常駐的兩個邊防站編號, Ci號邊防站沿順時針方向至Di號邊防站力他的奔襲區間。數據保證整個邊境線都是可被覆蓋的。輸出
輸出數據僅1行,需要包含n個正整數。其中,第j個正整數表示j號邊防戰士必須參加的前提下至少需要 多少名邊防戰士才能順利地完成國旗計劃樣例輸入
4 8
2 5
4 7
6 1
7 3
樣例輸出
3 3 4 3
題解
倍增
如果將選擇的區間按照右端點正方向順序考慮的話,那么如果選擇了某個區間,下一個區間的選擇一定是所有左端點小于等于該區間右端點中,右端點最靠后的那一個。
因此首先斷環成鏈,然后選擇區間 $[l,r]$ 后,下一個選擇就應該是左端點在 $[1,r]$ 范圍內,右端點最靠后的。
所以對于每一個區間 $[l,r]$ ,在 $l$ 位置上加入 $r$ ,然后求前綴最大值即可得到每個位置選上一個區間后最遠能夠覆蓋到哪。
我們要求的是覆蓋整個圈,因此可以考慮倍增算法,預處理出 $f[i][j]$ 表示從 $j$ 位置選擇 $2^i$ 段區間最遠能夠覆蓋到哪。那么上面的全椎最大值就是 $f[0][j]$ 。
根據遞推式 $f[i][j]=f[i-1][f[i-1][j]]$ 預處理出 $f$ 數組,然后倍增求解。從大到小枚舉 $i$ ,如果加入一段不能覆蓋整個圈則加入,否則不加入。最后加上2(本身+無限逼近后剩余的一段)即為答案。
注意一下區間跨越 $m$ 的處理 ,詳見代碼。
時間復雜度 $O(n\log n)$
#include <cstdio> #include <cstring> #include <algorithm> #define N 200010 #define pos(x) lower_bound(v + 1 , v + m + 1 , x) - v using namespace std; int a[N] , b[N] , v[N << 1] , f[20][N << 2]; int main() {int n , m = 0 , i , j , t , ans;scanf("%d%*d" , &n);for(i = 1 ; i <= n ; i ++ ) scanf("%d%d" , &a[i] , &b[i]) , v[++m] = a[i] , v[++m] = b[i];sort(v + 1 , v + m + 1);for(i = 1 ; i <= n ; i ++ ){a[i] = pos(a[i]) , b[i] = pos(b[i]);if(a[i] < b[i]){f[0][a[i]] = max(f[0][a[i]] , b[i]);f[0][a[i] + m] = max(f[0][a[i] + m] , b[i] + m);}else{f[0][1] = max(f[0][1] , b[i]);f[0][a[i]] = max(f[0][a[i]] , b[i] + m);f[0][a[i] + m] = max(f[0][a[i] + m] , m << 1);}}for(i = 1 ; i <= m << 1 ; i ++ ) f[0][i] = max(f[0][i] , f[0][i - 1]);for(t = 1 ; (1 << t) <= m << 1 ; t ++ )for(i = 1 ; i <= m << 1 ; i ++ )f[t][i] = f[t - 1][f[t - 1][i]];for(i = 1 ; i <= n ; i ++ ){ans = 0;if(a[i] < b[i]) a[i] += m;for(j = t - 1 ; ~j ; j -- )if(f[j][b[i]] < a[i])ans += (1 << j) , b[i] = f[j][b[i]];printf("%d" , ans + 2);if(i < n) printf(" ");}return 0; }?
轉載于:https://www.cnblogs.com/GXZlegend/p/8029235.html
總結
以上是生活随笔為你收集整理的【bzoj4444】[Scoi2015]国旗计划 倍增的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 完整版身份证前6位判断归属地
- 下一篇: 获得变量的名称获得传入参数的参数类型与堆