codeforces 1793D Moscow Gorillas
https://codeforces.com/contest/1793/problem/D
解题思路
依次找出 MEX = 1..n+1的序列数量就能得解。
MEX = n+1 只有全序列这一种情况。
MEX = 1时,找出两个序列中1的位置,较小位置左边的元素构成的子序列,较大位置右边的元素构成的子序列,以及两个位置中间的元素构成的子序列都满足。
MEX = i (i∈2...n) 时,找出两个序列同时包含 1~i-1 的最短子序列,记为S。如果 i 在S中,则无解。否则,根据 i 在两个序列中的位置,计算可能的序列组合数。下一轮计算两个序列同时包含 1~i 的最短子序列的范围,可以根据S的范围以及 i 的位置进行推导。
/* https://codeforces.com/problemset/problem/1793/D */ #include <bits/stdc++.h> using namespace std; #define N 200001 int n, p[N], q[N]; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); while (cin >> n) { int tmp; for (int i = 1; i <= n; i++) { cin >> tmp; p[tmp] = i; } for (int i = 1; i <= n; i++) { cin >> tmp; q[tmp] = i; } int64_t ans = 1, l, r, prel, prer; prel = l = min(p[1], q[1]); prer = r = max(p[1], q[1]); ans += (l-1)*l/2; ans += (n-r+1)*(n-r)/2; ans += (r-l)*(r-l-1)/2; for (int i = 1; i < n; i++) { l = min(p[i], q[i]); r = max(p[i], q[i]); l = min(l, prel), r = max(r, prer); if ((l <= p[i+1] && p[i+1] <= r) || (l <= q[i+1] && q[i+1] <= r)) { prel = l, prer = r; continue; } int ml = 1, mr = n; int left = min(p[i+1], q[i+1]); int right = max(p[i+1], q[i+1]); ml = left+1 <= l ? left+1 : ml; ml = right+1 <= l ? right+1 : ml; mr = right-1 >= r ? right-1 : mr; mr = left-1 >= r ? left-1 : mr; int64_t nl = l - ml, nr = mr - r; // cout << "..." << i << " [" << l << "," << r << "] " << nl * nr + nl + nr + 1 << endl; ans += nl * nr + nl + nr + 1; prel = l, prer = r; } cout << ans << endl; } return 0; }
分类:
ACM
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】