CodeForces - 731D 80-th Level Archeology

/*
  这题弄懂的过程可谓相当艰难...为了弄懂差分法和线段扫描法,我大约参考了四串代码(当然,其实看代码不是最难的,最难的是,我知道代码的语义,可是不知道为什么要那样写...)下面贴四个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;
}


posted @ 2017-08-26 09:26  mofushaohua  阅读(301)  评论(0编辑  收藏  举报