如果乙個序列裡沒有只出現一次的元素,那麼這個序列顯然是無聊的。
如果乙個序列裡有乙個出現一次的元素a[k],那麼對於這個序列無聊或不無聊的判斷,只需判斷[1,,k-1]和[k+1,n]是不是無聊的。
所以就可以遞迴下去,那麼我們現在的問題就變為如何找到乙個只出現一次的元素。預處理好每個數的前驅,後繼,掃一遍,判斷是否在區間內即可。
不過問題來了,設檢查長度為n的序列花費t(n)的時間,則有t(n)=max,若我們從左往右掃,最壞情況就是k在末尾,即t(n)=t(n-1)+o(n)=o(n^2),從右往左同理。
那麼,我們可以採用從兩邊往中間找的方法。那上述的最壞情況就變成了t(n)=t(n-1)+o(1),而此時的最壞情況即元素在中間,滿足經典遞推式——t(n)=2t(n/2)+o(n),即o(nlogn)
#includeconst int n=200005;
const int inf=0x3f3f3f3f;
using namespace std;
templateinline void read(t &x)
mapm;
int n,num[n],last[n],next[n];
inline bool solve(int l,int r)
return false;
}int main()
m.clear();
for(int i=n;i>=1;i--)
if(solve(1,n)) puts("non-boring");
else puts("boring");
} return 0;
}
UVa1608 不無聊的數列
題意 乙個長度為n序列,如果這個任意連續子串行的中都有至少有乙個只出現一次的元素,那麼就稱這個序列是不無聊的,判斷這個序列是不是無聊的。思路 分治 先將整個序列掃瞄一遍,找到只出現一次的元素,如果沒有,則這個序列是無聊的。如果找到了a k 那麼只需要檢查 l,k 1 和 k 1,r 關鍵是如何找到這...
UVA 1608 啟發式分治
題目大意 給乙個序列,問這個序列無不無聊,不無聊序列的定義是任意的連續序列中都能找到乙個只出現過一次的數字 題目思路 首先給乙個序列,這個序列中滿足有乙個只出現過一次的數字,那麼,在這個序列中,所有跨過這個數字的區間一定都是不無聊的,所以想出現無聊的數字一定得在兩邊找,那麼就可以想到利用分治。然後使...
uva 1608 分治 中途相遇法
參考紫書,利用stl map,找到陣列中相同元素的關係。每找到乙個所求範圍唯一元素,對元素所在的範圍進行分治。注意 不能用prev和next作陣列名會使juge無法判斷 include includeusing namespace std const int maxn 200000 5 int nu...