D. Mysterious Crime(枚举暴力,思维)

, , n 2 ! 开始脑子抽了,以为不能暴力,毕竟枚举子段有n^2种呢!

直接上不需要每个都去枚举

比如拿第一个人的排列作为母串

1 , m , 以1开头,匹配所有的m个排列,看下最多匹配到哪里

s , s + 1 设最多匹配到位置s,那么下一次直接枚举s+1位置开头的子串

? 1 s , ( s + 1 ) s / 2 为什么?因为1到s的所有子串都满足条件,直接加上(s+1)*s/2

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5+10;
int n,m;
int a[11][maxn],vis[11][maxn],ans;
signed main()
{
	cin >> n >> m;
	for(int i=1;i<=m;i++)
	for(int j=1;j<=n;j++)
	{
		scanf("%lld",&a[i][j]);
		vis[i][ a[i][j] ] = j;
	}
	for(int j=1;j<=n;j++)//以j开头
	{
		int temp=1;//至少相同一个 
		while(temp<=n-j)//最多能到n-j+1 
		{
			int standard=a[1][j+temp],flag=1;
			for(int q=2;q<=m;q++)
			{
				int num=vis[q][a[1][j]]+temp;
				if(a[q][num]==standard)	continue;
				else	flag=0;
			}
			if(flag==0)	break;
			temp++;//成功就加一个 
		}
		j+=(temp-1);
		ans += temp*(temp+1)/2;
	}
	cout<<ans; 
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/106854008