「Two permutations」Solution

简述题意

给定两个长度为 n n n 的排列 a , b a,b a,b,以及 q q q 次询问,每次询问给定 l 1 , r 1 , l 2 , r 2 l_1,r_1,l_2,r_2 l1,r1,l2,r2,求出有多少个数 x x x 满足 x ∈ a i , i ∈ [ l 1 , r 1 ] x\in{a_{i}},i\in[l_1,r_1] xai,i[l1,r1] x ∈ b i , i ∈ [ l 2 , r 2 ] x \in b_i, i \in[l_2,r_2] xbi,i[l2,r2],强制在线。

思路

这种板子题评紫

注意到每个数仅出现一次,所以不妨令 a i a_i ai b b b 排列中出现的位置为 t o i to_i toi,每次查询 [ l 1 , r 1 ] [l_1,r_1] [l1,r1] 中有多少个 t o i to_i toi 满足 l 2 ≤ t o i ≤ r 2 l_2 \le to_i \le r_2 l2toir2 即可。特定区间值域查询,一眼主席树。

代码

注意这道题有点卡空间,不要乱开。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1.2e6 + 5;
int n , m , a[MAXN] , b[MAXN] , lastans = -1;
namespace Segement{
	static int tot , rt[MAXN] , root;
	struct tree{
		int l , r , sum , ls , rs;
	}tree[MAXN * 20];
	int build(int p , int l , int r) {
		p = ++ tot;
		tree[p].l = l , tree[p].r = r;
		if (l == r) return p;
		int mid = l + r >> 1;
		tree[p].ls = build(p , l , mid) , tree[p].rs = build(p , mid + 1 , r);
		return p;
	}
	int newnode(int p) {
		tree[++ tot] = tree[p];
		return tot;
	}
	int update(int p , int x) {
		int now = newnode(p);
		tree[now].sum ++;
		if (tree[now].l == tree[now].r) return now;
		int mid = tree[now].l + tree[p].r >> 1;
		if (x <= mid) tree[now].ls = update(tree[now].ls , x);
		else tree[now].rs = update(tree[now].rs , x);
		return now;
	}
	int query(int p , int p2 , int l , int r) {
		if (tree[p].l >= l && tree[p].r <= r) return tree[p2].sum - tree[p].sum;
		int mid = tree[p].l + tree[p].r >> 1 , tmp = 0;
		if (l <= mid) tmp += query(tree[p].ls , tree[p2].ls , l , r);
		if (r > mid) tmp += query(tree[p].rs , tree[p2].rs , l , r);
		return tmp;
	}
}
using namespace Segement;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr) , cout.tie(nullptr);
	cin >> n;
	for (int i = 1 ; i <= n ; i ++) cin >> a[i];
	for (int i = 1 , x ; i <= n ; i ++) cin >> x , b[x] = i;
	rt[0] = build(1 , 1 , n);
	for (int i = 1 ; i <= n ; i ++) rt[i] = update(rt[i - 1] , b[a[i]]);
	cin >> m;
	while(m --) {
		int a , b , c , d;
		cin >> a >> b >> c >> d;
		int l1 = (a + lastans) % n + 1 , r1 = (b + lastans) % n + 1;
		int l2 = (c + lastans) % n + 1 , r2 = (d + lastans) % n + 1;
		if (l1 > r1) swap(l1 , r1);
		if (l2 > r2) swap(l2 , r2);
		cout << (lastans = query(rt[l1 - 1] , rt[r1] , l2 , r2)) << '\n';
	}
	return 0;
}

相关推荐

  1. 「Destiny」Solution

    2024-04-21 08:12:03       36 阅读
  2. 「Two permutations」Solution

    2024-04-21 08:12:03       38 阅读
  3. AWS Certified Solutions Architect

    2024-04-21 08:12:03       24 阅读
  4. 「Pudding Monsters」Solution

    2024-04-21 08:12:03       33 阅读
  5. Solution Set 2023.12.4

    2024-04-21 08:12:03       45 阅读
  6. 「Nastya Hasn‘t Written a Legend」Solution

    2024-04-21 08:12:03       32 阅读
  7. solus linux 简介

    2024-04-21 08:12:03       25 阅读
  8. Solus Linux简介

    2024-04-21 08:12:03       26 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-21 08:12:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-21 08:12:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-04-21 08:12:03       82 阅读
  4. Python语言-面向对象

    2024-04-21 08:12:03       91 阅读

热门阅读

  1. 【Linux开发 第五篇】vi和vim

    2024-04-21 08:12:03       38 阅读
  2. 基于OKHttp的大文件下载

    2024-04-21 08:12:03       36 阅读
  3. Promise

    2024-04-21 08:12:03       41 阅读
  4. 根据哈夫曼树求哈夫曼编码

    2024-04-21 08:12:03       36 阅读
  5. Edge的使用心得与深度探索

    2024-04-21 08:12:03       34 阅读
  6. CentOS 7 文件权限管理详解

    2024-04-21 08:12:03       37 阅读
  7. 软考高级架构师:软件需求管理例题解析

    2024-04-21 08:12:03       34 阅读