給定乙個整數陣列a,分別求出滿足下列條件的子串數量:
1)子串[l, r]中的最大值為a[r];
2)子串[l, r]中的最小值為a[l],最大值為a[r]
注意是子串不是子串行,第一問要求o(n)的時間複雜度,第二問要求o(n*lgn)
第一小問,對於a中的每個元素a[i],我們定義prev[i]:在a[i]之前第乙個比它大的數的下標,如果沒有這樣的數則prev[i]=-1。以a[i]為右端點和最大數的子串個數等於(i - prev[i])。求prev[i]的過程是線性的。
第二小問,維護乙個陣列q,q中每個元素是乙個pair,兩個元素分別對應a[i]和i。q存的是當前所有可以作為左端點的a中元素,q中value是非減的,index是遞增的。插入乙個新的pair時,統計一下在當前q中index大於prev[j]的元素個數,這就是a[j]作為右端點的合法子串個數(q中元素都是合法左端點)。同時,在q中二分找到第乙個value比a[j]大的元素q[k],刪除q[k]和它之後的所有元素,保證q中元素作為左端點的合法性。
#include typedef long long ll;
typedef std::pairpii;
#define mp std::make_pair
#define fi first
#define se second
const int maxn = 2e5 + 4;
ll ans1, ans2;
int n, a[maxn], prev[maxn], qsz;
pii q[maxn];
void solve1()
prev[i] = idx;
ans1 += i - prev[i];
}std::cout << ans1 << std::endl;
}inline bool ok1(int x, int y)
int binarysearch1(int x)
return l;
}inline bool ok2(int x, int y)
int binarysearch2(int x)
return l;
}void solve2()
std::cout << ans2 << std::endl;
}int main()
solve1();
solve2();
return 0;
}
一道面試題
一道面試題 射擊運動員10發打中90環有多少種可能,請編寫程式計算出來,並列印出結果,0環和10環均有效。打中90環就是沒打中10環,所以打中90環跟打中10環的可能性是一樣的。然後開始遞迴狂打槍,一到10就記錄 if params i 10 在迴圈的控制中已經排除了大於10的可能性 i 10 pa...
一道面試題
前些時候在找工作,就在準備結束此次找工作歷程的時候,去了一家公司面試,去了之後技術經理直接帶到一台電腦旁,給了一張紙條,上面是這樣的題目 用c或c 來實現 1 建立一棵樹,該樹的深度是隨機的,每個節點的位元組點數是隨機的。2 給每個節點分配一段隨機大小的記憶體空間,給每個節點賦乙個隨機數。3 遍歷這...
一道面試題
如果n為偶數,則將它除以2,如果n為奇數,則將它加1或者減1。問對於乙個給定的n,怎樣才能用最少的步驟將它變到1。例如 n 61 n 60 n 2 30 n 2 15 n 16 n 2 8 n 2 4 n 2 2 n 2 1 public class myclass public static vo...