Mysterious Crime CodeForces - 1043D (思維+組合數學)
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
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
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
Input3 2Output
1 2 3
2 3 1
4Input
5 6Output
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
2 2Output
1 2
2 1
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.
題意:
給你k個互不相同的1~n的全排列,
求這k個排列有多少個公共子序列。
思路:
這題關鍵的一點是全排列的性質,每一個數都僅且出現1次。
利用這個性質,我們可以建立一個pre數組,a[i] [x ] 表示的是在第i個全排列中 x這個數前面的數。
那麽我們只需要從一個全排列下手,來求他的子序列是否也是其他全部排列的子序列,
利用一個cnt變量來維護當前已經滿足條件的子序列長度。
如果當前的全排列x前面的數y,其他的全排列中x前面的數也是y,那麽cnt++,否則把cnt賦值為1,(一個數也是滿足條件的子序列)
(上面用到的是組合數學的性質,即3個長度的序列有 3+2+1個子序列 那麽維護的時候加起來也是1+2+3 )
細節見代碼:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <iomanip> #define ALL(x) (x).begin(), (x).end() #define rt return #define dll(x) scanf("%I64d",&x) #define xll(x) printf("%I64d\n",x) #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), ‘\0‘, sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) #define db(x) cout<<"== [ "<<x<<" ] =="<<endl; using namespace std; typedef long long ll; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;} inline void getInt(int* p); const int maxn=1000010; const int inf=0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ int pre[maxn]; int a[12][100005]; int n,k; int main() { //freopen("D:\\common_text\\code_stream\\in.txt","r",stdin); //freopen("D:\\common_text\\code_stream\\out.txt","w",stdout); gbtb; cin>>n>>k; repd(i,1,k) { repd(j,1,n) { cin>>pre[j];// pre數組中最終存的是最後一行的值 a[i][pre[j]]=pre[j-1]; // a[i][j] 表示第i個全排列中,j之前的數 } } ll cnt=0; ll ans=0; repd(j,1,n) { int isok=1; repd(i,1,k-1) { if(a[i][pre[j]]!=pre[j-1])// 判斷第i行中是否存在最後一行的第j 位和第j-1 位 { isok=0; break; } } if(isok) { cnt++; }else { cnt=1; } ans+=cnt; } cout<<ans<<endl; return 0; } inline void getInt(int* p) { char ch; do { ch = getchar(); } while (ch == ‘ ‘ || ch == ‘\n‘); if (ch == ‘-‘) { *p = -(getchar() - ‘0‘); while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) { *p = *p * 10 - ch + ‘0‘; } } else { *p = ch - ‘0‘; while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) { *p = *p * 10 + ch - ‘0‘; } } }
Mysterious Crime CodeForces - 1043D (思維+組合數學)