1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > codeforces:C. Foe Pairs【排列 + 子数组个数问题 + 排序 + 二分】

codeforces:C. Foe Pairs【排列 + 子数组个数问题 + 排序 + 二分】

时间:2020-09-01 22:42:56

相关推荐

codeforces:C. Foe Pairs【排列 + 子数组个数问题 + 排序 + 二分】

分析

求得是不能包含任意两个数字得子数组个数

那么排列问题当然要求数字对应得下标,把查询得两个数都转换为下标

得到m组下标对

然后按右端点排序

我们得思路是固定r,看看l最左到哪里

那么我们固定r,肯定对于右端点来说落在某两个中间

然后它左边得所有左端点都要满足l大于这个左端点

所以要维护左端点前缀最大值

然后就可以得到最左边得l了

Ac code

import sysfrom bisect import bisect_rightinput = sys.stdin.readlinen, m = list(map(int, input().split()))p = list(map(int, input().split()))pairs = []for _ in range(m):x, y = list(map(int, input().split()))pairs.append([x, y])idx = [0] * (n + 1)for i, v in enumerate(p):idx[v] = i + 1for i in range(m):pairs[i][0] = idx[pairs[i][0]]pairs[i][1] = idx[pairs[i][1]]if pairs[i][0] > pairs[i][1]:pairs[i][0], pairs[i][1] = pairs[i][1], pairs[i][0]pairs.sort(key = lambda x: x[1])maxleft = [0] * mfor i in range(m):if i == 0:maxleft[i] = pairs[i][0]else:maxleft[i] = max(maxleft[i - 1], pairs[i][0])rr = [r for _, r in pairs]ans = 0# fix r# most left lfor r in range(1, n + 1):idx = bisect_right(rr, r)if idx == 0:ans += relse:maxnl = maxleft[idx - 1]ans += r - maxnlprint(ans)

总结

子数组个数问题

固定一端,看看另一端最大取到哪里

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。