/* 这题弄懂的过程可谓相当艰难...为了弄懂差分法和线段扫描法,我大约参考了四串代码(当然,其实看代码不是最难的,最难的是,我知道代码的语义,可是不知道为什么要那样写...)下面贴四个blog,里面的解析,对于理解代码和理解这两种方法,非常重要!! http://blog.csdn.net/h1021456873/article/details/53240994 http://www.cnblogs.com/agenthtb/p/5998819.html http://www.cnblogs.com/iRedBean/p/5975561.html http://blog.csdn.net/morejarphone/article/details/52852161 以及,这题后来还RE了几次,发现是我太粗心了,a数组和d数组的维度是不同的,前者约是n的上限,后者约是c的上限,两个上限不同,就算要以一种代替所有,也应该选c的上限,才不会越界...可因为我的粗心,运行错误了几次,戒之慎勿忘!!! */
#include <bits/stdc++.h> using namespace std; const int N = 5e5 + 10; const int M = 1e6 + 10; vector<int>a[N]; int d[M]; void work(int l, int r) { d[l]++; d[r + 1]--; } int main() { cin.tie(0); cin.sync_with_stdio(false); memset(d, 0, sizeof(d)); int n, c, m, tp, i, j, x, y; cin >> n >> c; int sum = 0, flag = 1; for ( i = 1; i <= n; i++ ) { a[i].clear(); cin >> m; a[i].push_back(m); for ( j = 1; j <= a[i][0]; j++ ) { cin >> m; a[i].push_back(m); } } for ( i = 1; i < n; i++ ) { tp = min(a[i][0], a[i+1][0]); for ( j = 1; j <= tp; j++) { x = a[i][j]; y = a[i + 1][j]; if ( x != y) break; } if (j > tp && a[i][0] > a[i+1][0]) { cout << -1 << endl; return 0; } if ( y > x ) { work(0, c - y); work(c + 1 - x, c - 1); } else if ( x > y ) { work(c + 1 - x, c - y ); } else work(0, c - 1); } for (int i = 0; i < c; i++) { sum += d[i]; if ( sum == n - 1) { cout << i << endl; flag = 0; break; } } if (flag) cout << -1 << endl; return 0; }