Prefix Equality(树状数组维护区间最值)

#include 
using namespace std;
const int N = 2e5 + 10, INF = 0x3f3f3f3f;

int n, m;
//tr[i]维护a数组前i个数最大值在b数组中出现的最早位置
//tr1[i]维护b数组前i个数最大值在a数组中出现的最早位置
int a[N], b[N], id[N], id1[N], tr[N], tr1[N];
unordered_map <int, int> mp, mp1;
int lowbit(int x)  // 返回末尾的1
{
    return x & -x;
}

void add (int tr[], int x, int k)
{
    for (int i = x; i <= n; i += lowbit (i))
        tr[i] = max (tr[i], k);
}

int query (int tr[], int x)
{
    int res = 0;
    for (int i = x; i; i -= lowbit (i))
        res = max (tr[i], res);

    return res;
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ ) cin >> a[i];
    for (int i = 1; i <= n; i ++ ) cin >> b[i];
    //mp记录b数组每个数最早出现位置的下标
    //mp1记录a数组每个数最早出现位置的下标
    for (int i = n; i >= 1; i --) mp[b[i]] = i;
    for (int i = n; i >= 1; i --) mp1[a[i]] = i;
    
    for (int i = 1; i <= n; i ++)
    {
    	//INF作用见下面注释
        if (mp[a[i]] != 0) id[i] = mp[a[i]];
        else id[i] = INF;
        if (mp1[b[i]] != 0) id1[i] = mp1[b[i]];
        else id1[i] = INF;
        add (tr, i, id[i]);
        add (tr1, i, id1[i]);
    }
    cin >> m;
    while (m --)
    {
        int a, b; cin >> a >> b;
        /*如果没有INF,只靠这两个判断会忽略掉
        1 2 3 4 5
		1 2 2 4 3
		查询为 5 5的情况,即a中的5在b中没有的情况
        */
        if (query (tr, a) <= b && query (tr1, b) <= a)   cout << "Yes\n";
        else cout << "No\n";
    }
    
    return 0;
}

你可能感兴趣的:(c++,算法,数据结构)