CF1043D Mysterious Crime
Posted wangyiming
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1043D Mysterious Crime相关的知识,希望对你有一定的参考价值。
思路:
参考了http://codeforces.com/blog/entry/62797,把第一个序列重标号成1,2,3,...,n,在剩下的序列中寻找形如x, x + 1, x + 2, ...的连续子段即可。
实现:
1 #include <iostream> 2 #include <vector> 3 #include <cstring> 4 using namespace std; 5 typedef long long ll; 6 7 const int INF = 0x3f3f3f3f; 8 9 int a[11][100001], reach[11][100001], n, m; 10 11 int main() 12 { 13 while (scanf("%d %d", &n, &m) != EOF) 14 { 15 memset(reach, 0, sizeof reach); 16 for (int i = 1; i <= m; i++) 17 { 18 for (int j = 1; j <= n; j++) 19 scanf("%d", &a[i][j]); 20 } 21 vector<int> v(n + 1); 22 for (int i = 1; i <= n; i++) v[a[1][i]] = i; 23 for (int i = 2; i <= m; i++) 24 { 25 for (int j = 1; j <= n; j++) 26 a[i][j] = v[a[i][j]]; 27 } 28 for (int i = 1; i <= n; i++) reach[1][i] = n; 29 for (int i = 2; i <= m; i++) 30 { 31 int j = 1, start = 1; 32 while (j <= n) 33 { 34 while (j + 1 <= n && a[i][j + 1] == a[i][j] + 1) j++; 35 while (start <= j) { reach[i][a[i][start]] = a[i][j]; start++; } 36 start = ++j; 37 } 38 } 39 ll ans = 0; 40 for (int i = 1; i <= n; i++) 41 { 42 int minn = INF; 43 for (int j = 1; j <= m; j++) 44 if (reach[j][i]) 45 minn = min(minn, reach[j][i] - i + 1); 46 if (minn != INF) ans += minn; 47 } 48 printf("%lld ", ans); 49 } 50 return 0; 51 }
以上是关于CF1043D Mysterious Crime的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #519 D - Mysterious Crime
[题解]Codeforces Round #519 - D. Mysterious Crime