1 /*
2 Source :CF689D
3 题意:给出a,b两个长度为n的数组,问有多少个区间满足max(a[l,r])==min(b[l,r]) len(a)<10^5
4 思路:对于一个固定的l,max(a[l,r])是一个单调不减的序列,min(b[l,r])是一个单调不增的序列,
5 于是可以枚举区间的左端点,然后二分判断右端点的范围
6 快速查询区间的最大最小值可以利用ST表实现。
7 时间 :2018-08-14-12.26
8 */
9 #include <bits/stdc++.h>
10 using namespace std;
11
12 typedef long long LL;
13 const int MAXN=200005;
14 const LL MOD7 = 1e9+7;
15
16 struct Min_STable
17 {
18 // int a[MAXN];
19 int dp[MAXN][20];
20 void init(int *a, int n)
21 {
22 for (int i=1;i<=n;++i) dp[i][0]=a[i];
23 for (int j=1;(1<<j)<=n;++j)
24 {
25 for (int i=1;i+(1<<j)-1<=n;++i)
26 {
27 dp[i][j]=(dp[i][j-1]<dp[i+(1<<(j-1))][j-1]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1]);
28 }
29 }
30 }
31 int query(int x,int y)
32 {
33 if (x>y) swap(x,y);
34 int k=log(y-x+1)/log(2);
35 return (dp[x][k]<dp[y-(1<<k)+1][k]?dp[x][k]:dp[y-(1<<k)+1][k]);
36 }
37 }Min_st;
38
39 struct Max_STable
40 {
41 int dp[MAXN][20];
42 void init(int *a,int n)
43 {
44 for (int i=1;i<=n;++i) dp[i][0]=a[i];
45 for (int j=1;(1<<j)<=n;++j)
46 {
47 for (int i=1;i+(1<<j)-1<=n;++i)
48 {
49 dp[i][j]=(dp[i][j-1]>dp[i+(1<<(j-1))][j-1]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1]);
50 }
51 }
52 }
53 int query(int x,int y)
54 {
55 if (x>y) swap(x,y);
56 int k=log(y-x+1)/log(2);
57 return (dp[x][k]>dp[y-(1<<k)+1][k]?dp[x][k]:dp[y-(1<<k)+1][k]);
58 }
59 }Max_st;
60
61 int a[MAXN];
62 int b[MAXN];
63 int n;
64
65 void work()
66 {
67 Max_st.init(a,n);
68 Min_st.init(b,n);
69 LL ans=0;
70 for (int i=1;i<=n;++i)
71 {
72 if (a[i]>b[i]) continue;
73 if (Max_st.query(i,n)<Min_st.query(i,n)) continue;
74 int l=i,r=n;
75 int ml;
76 while (l<=r)
77 {
78 ml=(l+r)/2;
79 // printf("l=%d r=%d ml=%d id_A=%d id_B=%d max_A=%d min_b=%d\n",l,r,ml,Max_st.query(a,i,ml),Min_st.query(b,i,ml),a[Max_st.query(a,i,ml)],b[Min_st.query(b,i,ml)]);
80 if (Max_st.query(i,ml)>=Min_st.query(i,ml)) r=ml-1;
81 else l=ml+1;
82 }
83 if (Max_st.query(i,r+1)!=Min_st.query(i,r+1)) continue;
84 int pl = r+1;
85 l=i,r=n;
86 while (l<=r)
87 {
88 ml=(l+r)/2;
89 // printf("2 l=%d r=%d ml=%d\n",l,r,ml);
90 if (Max_st.query(i,ml)<=Min_st.query(i,ml)) l=ml+1;
91 else r=ml-1;
92 }
93 ans+=(LL) (l-pl);
94 }
95 printf("%I64d\n",ans);
96 }
97
98 int main()
99 {
100 #ifndef ONLINE_JUDGE
101 freopen("test.txt","r",stdin);
102 #endif // ONLINE_JUDGE
103 scanf("%d",&n);
104 for (int i=1;i<=n;++i) scanf("%d",&a[i]);
105 for (int i=1;i<=n;++i) scanf("%d",&b[i]);
106 work();
107 return 0;
108 }
109
110 //in[1]:
111 //6
112 //1 2 3 2 1 4
113 //6 7 1 2 3 2
114
115 //out[1]:
116 //2