题目传送门

题目大意:

  给出m个1-n的全排列,问这m个全排列中有几个公共子串。

思路:

  首先单个的数字先计算到答案中,有n个。

  然后考虑多个数字,如果有两个数字相邻,那么在m个串中必定都能找到这两个数字并且位置相邻。那么我们枚举1-n所有的数字,比如先枚举p1是1,那p2就是在全排列1中p1后面的数字,然后往下面找,看看下面的全排列,p2是不是也在p1的后面,如果是的话,再看p3是不是在p2的后面。

  要注意的是,如果我们发现p2在p1的后面,那么我们就把p1p2连起来,合并到dp[1][p1]中(实际上最好用p1的位置当成第二维参数),并且标记一下,下次如果找到了一个被标记过的数字,我们就可以直接把

dp[1][p1]*dp[1][p2]累加到答案中,p2后面的片段就不需要再次扫描了。

  时间复杂度的话,每个元素最多和后面连一次,和前面连一次,所以最多被扫两次(实际上应该是1次,因为这个两次重复计算了,要除以2)。也就是说时间复杂度是O(nm)级别的。

  

//#pragma comment(linker,"/STACK:102400000,102400000")
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<stdlib.h>
//#include<unordered_map>
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)|1
#define CLR(a,b) memset(a,b,sizeof(a))
#define mkp(a,b) make_pair(a,b)
typedef long long ll;
using namespace std;
inline ll read() {
ll x=,f=;
char ch=getchar();
while(ch<''||ch>'') {
if(ch=='-')f=-;
ch=getchar();
}
while(ch>=''&&ch<='') {
x=x*+ch-'';
ch=getchar();
}
return x*f;
}
const int maxn=1e5+;
int a[][maxn],pos[][maxn],n,m;
ll dp[][maxn];
bool vis[maxn];
ll ans;
int main() {
n=read(),m=read();
for(int i=; i<=m; i++) {
for(int j=; j<=n; j++) {
a[i][j]=read();
pos[i][a[i][j]]=j;
dp[i][j]=;
}
}
ans=n;
int flag;
for(int i=; i<=n; i++) {
int temp=pos[][i];//第一个指针
if(vis[temp])continue;
vis[temp]=;
int p1=i; //前元素
if(temp==n) {
continue;
}
int temp2=temp+;
int p2=a[][temp2];//后元素
flag=; while(flag) {
for(int k=; k<=m; k++) {
int xx=pos[k][p1];
if(a[k][xx+]==p2)continue;
flag=;
break;
}
if(flag) {
if(vis[temp2]==) { //已经访问过
ans+=(ll)dp[][temp]*dp[][temp2];
dp[][temp]+=dp[][temp2];
flag=;
} else {
ans+=(ll)dp[][temp]*dp[][temp2];
dp[][temp]+=dp[][temp2];
p1=p2;
vis[temp2]=;
temp2++;
if(temp2>n)break;
p2=a[][temp2];
} }
// printf("temp1:%d temp2:%d\n",temp,temp2);
} }
printf("%lld\n",ans);
}
D. Mysterious Crime
time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Acingel is a small town. There was only one doctor here — Miss Ada. She was very friendly and nobody has ever said something bad about her, so who could've expected that Ada will be found dead in her house? Mr Gawry, world-famous detective, is appointed to find the criminal. He asked mm neighbours of Ada about clients who have visited her in that unlucky day. Let's number the clients from 11 to nn. Each neighbour's testimony is a permutation of these numbers, which describes the order in which clients have been seen by the asked neighbour.

However, some facts are very suspicious – how it is that, according to some of given permutations, some client has been seen in the morning, while in others he has been seen in the evening? "In the morning some of neighbours must have been sleeping!" — thinks Gawry — "and in the evening there's been too dark to see somebody's face...". Now he wants to delete some prefix and some suffix (both prefix and suffix can be empty) in each permutation, so that they'll be non-empty and equal to each other after that — some of the potential criminals may disappear, but the testimony won't stand in contradiction to each other.

In how many ways he can do it? Two ways are called different if the remaining common part is different.

Input

The first line contains two integers nn and mm (1≤n≤1000001≤n≤100000, 1≤m≤101≤m≤10) — the number of suspects and the number of asked neighbors.

Each of the next mm lines contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n1≤ai≤n). It is guaranteed that these integers form a correct permutation (that is, each number from 11 to nn appears exactly once).

Output

Output a single integer denoting the number of ways to delete some prefix and some suffix of each permutation (possibly empty), such that the remaining parts will be equal and non-empty.

Examples
input

Copy
3 2
1 2 3
2 3 1
output

Copy
4
input

Copy
5 6
1 2 3 4 5
2 3 1 4 5
3 4 5 1 2
3 5 4 2 1
2 3 5 4 1
1 2 3 4 5
output

Copy
5
input

Copy
2 2
1 2
2 1
output

Copy
2
Note

In the first example, all possible common parts are [1][1], [2][2], [3][3] and [2,3][2,3].

In the second and third examples, you can only leave common parts of length 11.

最新文章

  1. 如何生成报告来枚举出整个sharepoint环境中的每个页面所使用的所有webpart
  2. C# 扩展方法集
  3. Java排序算法——冒泡排序
  4. Python中通过cx_oracle操作ORACLE数据库的封闭函数
  5. SQL Server数据库的三种恢复模式:简单恢复模式、完整恢复模式和大容量日志恢复模式(转载)
  6. Eclipse+pydev 常用快捷键
  7. CentOS对新加入的硬盘格式化
  8. Git错误non-fast-forward后的冲突解决(转载)
  9. 深入浅出Java并发包—锁机制(三)
  10. python之列表对象
  11. extern “ C”的含义
  12. Python dict和set的实现原理
  13. php 配置xdebug
  14. [译]C#7 Pattern Matching
  15. javascript五种基本类型
  16. vim相关
  17. python math random
  18. chrome书签(收藏栏)的导入导出
  19. Service里面启动Activity和Alertdialog
  20. 【转】The &amp;&amp; and || Operator in JavaScript

热门文章

  1. SQL Server误区30日谈 第26天 SQL Server中存在真正的“事务嵌套”
  2. spring 框架jdbc连接数据库
  3. 1-如何自己在eclipse上配置Andriod环境
  4. c语言数组初始化 蛋疼
  5. hdu1269 Tarjan强连通分量 模板(转)
  6. hdu 4768 Flyer (异或操作的应用)
  7. XE下 SVG格式的图标使用方法
  8. 细说Mammut大数据系统测试环境Docker迁移之路
  9. 图像中的掩膜(Mask)是什么
  10. vs2015+opencv3.3.1 +Eigen 3.3.4 c++ 实现 泊松图像编辑(无缝融合)