Equivalent Prefixes
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
Two arrays u and v each with m distinct elements are called equivalent if and only if
RMQ(u,l,r)=RMQ(v,l,r)RMQ(u,l,r)=RMQ(v,l,r) for all 1≤l≤r≤m1≤l≤r≤m
where RMQ(w,l,r)RMQ(w,l,r) denotes the index of the minimum element among wl,wl+1,…,wrwl,wl+1,…,wr.
Since the array contains distinct elements, the definition of minimum is unambiguous.
Bobo has two arrays a and b each with n distinct elements. Find the maximum number p≤np≤n where {a1,a2,…,ap}{a1,a2,…,ap} and {b1,b2,…,bp}{b1,b2,…,bp} are equivalent.
where RMQ(w,l,r)RMQ(w,l,r) denotes the index of the minimum element among wl,wl+1,…,wrwl,wl+1,…,wr.
Since the array contains distinct elements, the definition of minimum is unambiguous.
Bobo has two arrays a and b each with n distinct elements. Find the maximum number p≤np≤n where {a1,a2,…,ap}{a1,a2,…,ap} and {b1,b2,…,bp}{b1,b2,…,bp} are equivalent.
输入描述:
The input consists of several test cases and is terminated by end-of-file.
The first line of each test case contains an integer n.
The second line contains n integers a1,a2,…,ana1,a2,…,an.
The third line contains n integers b1,b2,…,bnb1,b2,…,bn.
* 1≤n≤1051≤n≤105
* 1≤ai,bi≤n1≤ai,bi≤n
* {a1,a2,…,an}{a1,a2,…,an} are distinct.
* {b1,b2,…,bn}{b1,b2,…,bn} are distinct.
* The sum of n does not exceed 5×1055×105.
输出描述:
For each test case, print an integer which denotes the result.
示例1
输入
2 1 2 2 1 3 2 1 3 3 1 2 5 3 1 5 2 4 5 2 4 3 1
输出
1 3 4
算法:ST表
思路:设置最小数的下标为pos = 0,依次添加一组数,并于前面的最小数进行比较,看此数是否符合条件,每次添加一组数有三种情况。
第一种:这组数全部小于最小数,这组数是可以的,更新最小数下标,判断下一组数。
第二种:这组数全部大于最小数,递归判断区间(pos + 1, r)里是否有最小数,如果有继续递归,直到l >= r时,返回true。如果没有返回false。
第三种:剩余的只有一种可能了,既有大于,也有小于,显然,这种可能时不存在的,直接跳出循环,输出结果。
#include <iostream> #include <cstdio> #include <cmath> using namespace std; typedef unsigned long long ull; int a[600005]; int b[600005]; int pos, n; int dpa[600005][20][2]; //三种状态: 1、当前区间的首元素的下标 // 2、从首元素开始延伸的的长度 // 3、0表示我当前期间内的最小值,1表示的当前区间内最小值的下标 int dpb[600005][20][2]; void ST_init() { for(int i = 0; i < n; i++) { dpa[i][0][0] = a[i]; dpa[i][0][1] = i; dpb[i][0][0] = b[i]; dpb[i][0][1] = i; } int nlen = (int)(log((double)(n)) / log(2.0)); for(int j = 1; j <= nlen; j++) { for(int i = 0; i < n; i++) { if(dpa[i][j - 1][0] < dpa[i + (1 << (j - 1))][j - 1][0]) { dpa[i][j][0] = dpa[i][j - 1][0]; dpa[i][j][1] = dpa[i][j - 1][1]; } else { dpa[i][j][0] = dpa[i + (1 << (j - 1))][j - 1][0]; dpa[i][j][1] = dpa[i + (1 << (j - 1))][j - 1][1]; } if(dpb[i][j - 1][0] < dpb[i + (1 << (j - 1))][j - 1][0]) { dpb[i][j][0] = dpb[i][j - 1][0]; dpb[i][j][1] = dpb[i][j - 1][1]; } else { dpb[i][j][0] = dpb[i + (1 << (j - 1))][j - 1][0]; dpb[i][j][1] = dpb[i + (1 << (j - 1))][j - 1][1]; } } } } bool ST_query(int l, int r) { if(l >= r) { //当查询区间小于1时,表示可行 return true; } int k = (int)(log((double)(r - l + 1)) / log(2.0)); int mina; int minb; if(dpa[l][k][0] < dpa[r - (1 << k) + 1][k][0]) { mina = dpa[l][k][1]; } else { mina = dpa[r - (1 << k) + 1][k][1]; } if(dpb[l][k][0] < dpb[r - (1 << k) + 1][k][0]) { minb = dpb[l][k][1]; } else { minb = dpb[r - (1 << k) + 1][k][1]; } if(mina == minb) { return ST_query(mina + 1, r); } return false; } int main() { while(~scanf("%d", &n)) { for(int i = 0; i < n; i++) { scanf("%d", &a[i]); } for(int i = 0; i < n; i++) { scanf("%d", &b[i]); } ST_init(); pos = 0; int i; for(i = 1; i < n; i++) { if(a[pos] > a[i] && b[pos] > b[i]) { pos = i; } else if(a[pos] < a[i] && b[pos] < b[i]) { if(!ST_query(pos + 1, i)) { break; } } else { break; } } printf("%d\n", i); } return 0; }