CodeForces 1043D Mysterious Crime 區間合並
題目傳送門
題目大意:
給出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> #includeView Code D. Mysterious Crime time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output<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) typedeflong long ll; using namespace std; inline ll read() { ll x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘)f=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘) { x=x*10+ch-‘0‘; ch=getchar(); } return x*f; } const int maxn=1e5+10; int a[11][maxn],pos[11][maxn],n,m; ll dp[11][maxn]; bool vis[maxn]; ll ans; int main() { n=read(),m=read(); for(int i=1; i<=m; i++) { for(int j=1; j<=n; j++) { a[i][j]=read(); pos[i][a[i][j]]=j; dp[i][j]=1; } } ans=n; int flag; for(int i=1; i<=n; i++) { int temp=pos[1][i];//第一個指針 if(vis[temp])continue; vis[temp]=1; int p1=i; //前元素 if(temp==n) { continue; } int temp2=temp+1; int p2=a[1][temp2];//後元素 flag=1; while(flag) { for(int k=2; k<=m; k++) { int xx=pos[k][p1]; if(a[k][xx+1]==p2)continue; flag=0; break; } if(flag) { if(vis[temp2]==1) { //已經訪問過 ans+=(ll)dp[1][temp]*dp[1][temp2]; dp[1][temp]+=dp[1][temp2]; flag=0; } else { ans+=(ll)dp[1][temp]*dp[1][temp2]; dp[1][temp]+=dp[1][temp2]; p1=p2; vis[temp2]=1; temp2++; if(temp2>n)break; p2=a[1][temp2]; } } // printf("temp1:%d temp2:%d\n",temp,temp2); } } printf("%lld\n",ans); }
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.
InputThe 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).
OutputOutput 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 Copy3 2output Copy
1 2 3
2 3 1
4input Copy
5 6output Copy
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
5input Copy
2 2output Copy
1 2
2 1
2Note
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.
CodeForces 1043D Mysterious Crime 區間合並