[CF731D]80-th Level Archeology

80-th Level Archeology

题解

很明显,要使序列A小于序列B所需操作次数的区间一定是连续的,在1到n的环上连续。

于是,我们可以先O\left(1 \right )地求出使前一个区间小于后一个区间的操作次数区间,然后通过差分将其加上去,最后只要找出所有区间都重合在一起的位置就好了。

源码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000005
#define lowbit(x) (x&-x)
typedef long long LL;
typedef pair<LL,LL> pii;
int n,c,cnt[MAXN],sum;
vector<int> s[MAXN*10];
void calc(int x,int y){
	int id=0;
	while(id<s[x].size()&&id<s[y].size()&&s[x][id]==s[y][id])id++;
	if(id<s[x].size()&&id<s[y].size()){
		if(s[x][id]<s[y][id])
			cnt[0]++,cnt[c-s[y][id]+1]--,
			cnt[c-s[x][id]+1]++,cnt[c]--;
		else
			cnt[c-s[x][id]+1]++,cnt[c-s[y][id]+1]--;
	}
	else if(id==s[x].size()&&id!=s[y].size())cnt[0]++,cnt[c]--;
	else if(id==s[y].size()&&id!=s[x].size());
	else cnt[0]++,cnt[c]--;
}
signed main(){
	scanf("%d %d",&n,&c);
	for(int i=1;i<=n;i++){
		int len;scanf("%d",&len);
		for(int j=1;j<=len;j++){
			int w;scanf("%d",&w);
			s[i].push_back(w);
		}
	}
	for(int i=2;i<=n;i++)calc(i-1,i);
	for(int i=0;i<c;i++){
		sum+=cnt[i];
		if(sum==n-1){printf("%d\n",i);return 0;}
	}
	puts("-1");
	return 0;
}

谢谢!!!

posted @ 2020-10-22 16:57  StaroForgin  阅读(10)  评论(0)    收藏  举报  来源