单调栈求第一个小于某个数的位置。
思路
这道题目需要求的是 a[l] % a[l + 1]… % a[r], 我们需要知道的是每次取模,如果a < b,那么取模没用,如果a > b,那么取模减小的数字至少是a的一半(我不知道啊。。。),那么这样的话,每次询问,最多取模的次数是Log(n), 问题就是我们需要预处理出小于当前数字的第一个数字的位置。这就用到了单调栈了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #include <iostream> #include <algorithm> #include <bitset> #include <cstring> #include <stack> using namespace std; typedef long long ll; int a[100005]; int nxt[100005]; int main() { int T,n; cin >> T; while(T--) { scanf("%d",&n); for(int i = 1; i <= n; ++i) scanf("%d",&a[i]); memset(nxt, -1, sizeof(nxt)); stack<int>S; for(int i = 1; i <= n; ++i) { while(!S.empty() && a[i] < a[S.top()]) { nxt[S.top()] = i; S.pop(); } S.push(i); } int Q,l,r; cin >> Q; while(Q--) { scanf("%d %d",&l,&r); int num = a[l]; while(nxt[l] != -1 && nxt[l] <= r) { num = num % a[nxt[l]]; l = nxt[l]; } cout << num << '\n'; } } }
|