D. Moscow Gorillas
D. Moscow Gorillas
In winter, the inhabitants of the Moscow Zoo are very bored, in particular, it concerns gorillas. You decided to entertain them and brought a permutation of length to the zoo.
A permutation of length is an array consisting of distinct integers from to in any order. For example, is a permutation, but is not a permutation ( occurs twice in the array) and is also not a permutation (, but is present in the array).
The gorillas had their own permutation of length . They suggested that you count the number of pairs of integers () such that .
The of the sequence is the minimum integer positive number missing from this sequence. For example, , , .
You do not want to risk your health, so you will not dare to refuse the gorillas.
Input
The first line contains a single integer () — the permutations length.
The second line contains integers () — the elements of the permutation .
The third line contains integers () — the elements of the permutation .
Output
Print a single integer — the number of suitable pairs and .
Examples
input
3 1 3 2 2 1 3
output
2
input
7 7 3 6 2 1 5 4 6 7 2 5 3 1 4
output
16
input
6 1 2 3 4 5 6 6 5 4 3 2 1
output
11
Note
In the first example, two segments are correct – with equal to in both arrays and with equal to in both of arrays.
In the second example, for example, the segment is correct, and the segment isn't correct, because .
解题思路
比赛的时候想到了通过枚举来计算每个对答案的贡献是多少,但没写出来。
先考虑的情况,首先选取的区间不能包含元素,那么和中能够选取的区间就被分成了个部分,长度分别为:
那么很明显共有个区间使得。
下面考虑的情况。
如果一个排列的区间满足,那么区间一定包含元素且一定不包含元素。定义表示元素在排列中的位置,表示前个元素中最小的下标位置,即,同理。因此如果某个区间的,那么就要满足或者,即不能在的范围内。
- 如果,那么满足的和要满足,。
- 如果,那么那么满足的和要满足,。
- 否则就是,此时没有区间满足。
现在是有两个排列和,那么对于同时满足和的区间可以对各自的和分别通过区间求交的方式得到:
在排列中,的取值范围是(红色部分),的取值范围是(绿色部分)。在中,的取值范围是(蓝色部分),的取值范围是(橙色部分)。
因此能够使得两个排列同时满足和的要满足,(记得选取的区间一定使得两个排列都包含元素),那么满足的区间个数就是,即分别是区间、、、、、。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 const int N = 2e5 + 10; 7 8 int p[N], q[N]; 9 int minp[N], maxp[N], minq[N], maxq[N]; 10 11 LL get(int a, int b, int c, int d) { // 区间[a,b]和[c,d]求交集 12 return max(0, min(b, d) - max(a, c) + 1); 13 } 14 15 LL cal(LL x) { // 计算1+2+...+x 16 return x * (x + 1) >> 1; 17 } 18 19 int main() { 20 int n; 21 scanf("%d", &n); 22 for (int i = 1; i <= n; i++) { 23 int x; 24 scanf("%d", &x); 25 p[x] = i; 26 } 27 for (int i = 1; i <= n; i++) { 28 int x; 29 scanf("%d", &x); 30 q[x] = i; 31 } 32 minp[1] = maxp[1] = p[1]; 33 minq[1] = maxq[1] = q[1]; 34 for (int i = 2; i <= n; i++) { 35 minp[i] = min(minp[i - 1], p[i]); 36 maxp[i] = max(maxp[i - 1], p[i]); 37 minq[i] = min(minq[i - 1], q[i]); 38 maxq[i] = max(maxq[i - 1], q[i]); 39 } 40 LL ret = 1; // 当两个排列都选区间[1,n]那么就有mex=n+1,这里的1就是指这个情况 41 for (int i = 2; i <= n; i++) { // 考虑mex=2~n的情况 42 if (p[i] >= minp[i - 1] && p[i] <= maxp[i - 1] || q[i] >= minq[i - 1] && q[i] <= maxq[i - 1]) continue; // 某个排列无法取得mex=i的区间 43 int lp, rp, lq, rq; 44 if (p[i] > maxp[i - 1]) lp = 1, rp = p[i] - 1; // p[i]在区间右边 45 else lp = p[i] + 1, rp = n; // p[i]在区间左边 46 if (q[i] > maxq[i - 1]) lq = 1, rq = q[i] - 1; // q[i]在区间右边 47 else lq = q[i] + 1, rq = n; //q[i]在区间左边 48 ret += get(lp, minp[i - 1], lq, minq[i - 1]) * get(maxp[i - 1], rp, maxq[i - 1], rq); // 区间求交,然后乘法原理计算答案 49 } 50 // 最后考虑mex=1的3个区间 51 ret += cal(get(1, p[1] - 1, 1, q[1] - 1)) + cal(max(0, abs(p[1] - q[1]) - 1)) + cal(get(p[1] + 1, n, q[1] + 1, n)); 52 printf("%lld", ret); 53 54 return 0; 55 }
参考资料
Codeforces Round #852 Editorial:https://codeforces.com/blog/entry/112723
Codeforces Round #852(Div. 2) D(枚举+分类讨论):https://zhuanlan.zhihu.com/p/605710274
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17117210.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2022-02-13 飞行员兄弟