codeforces D. Mysterious Crime(思維,公共子串)
阿新 • • 發佈:2018-12-21
求m個長度為n的序列(序列都是1到n的全排列之一),有多少個公共子串
題解:n的範圍1e5,m的範圍10,可以對每一個序列預處理求出每個字元後面的字元,nextz[i][a[i][j-1]]=nextz[i][a[i][j]],以第一個序列為基準,取一個數組fw[maxn],計算每一個位置的貢獻,其中fw[0]=0,其餘初始應該為1,然後對每一個位置,看這m個序列中的對應這個值的後面那個值是否都相同,累加貢獻值
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include <vector> #include <cmath> #include<queue> #include <stack> #include <map> #define maxn 100005 #define INF 0x3f3f3f3f #define LL long long using namespace std; int n,m; int a[20][maxn]; int nextz[20][maxn]; int fw[maxn]; int main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { cin>>a[i][j]; } for(int j=n;j>=1;j--) { nextz[i][a[i][j-1]]=a[i][j]; } } fw[0]=0; for(int i=0;i<n;i++) { int flag=0; int x=a[1][i]; for(int j=2;j<=m;j++) { if(nextz[j][x]!=a[1][i+1]) { flag=1; break; } } fw[i+1]=1; if(flag==0) fw[i+1]+=fw[i]; } LL ans=0; for(int i=1;i<=n;i++) { ans+=fw[i]; } cout << ans << endl; }