據說是什麼序列自動機? 咱們考慮對於每一個位置的串,下面拼接相同的字符時,拼接最近的一個,這樣能夠保證不重不漏 爲了實現這個咱們須要什麼呢,咱們須要一個鏈表,記錄一下每一個位置的下一個字符會轉移到哪裏 例如 ABAB ch[1]['A'] = 3 ch[1]['B'] = 2 聽起來挺好建的,具體能夠看代碼ios
而後咱們記錄dp[a][b]是第一個字符串a位置的字符爲開頭,第二個字符串b位置的字符爲開頭,公共子序列的個數 能夠記憶化搜索,每一次枚舉下一個位置拼接上哪一個字符 輸出方案的話也是同樣,枚舉下一個位置拼上哪一個字符this
後五個點須要高精度啊= =spa
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <cmath> #include <cstring> #include <map> //#define ivorysi #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define mp make_pair #define pb push_back #define fi first #define se second #define mo 974711 #define MAXN 3055 #define RG register using namespace std; typedef long long int64; typedef double db; template<class T> void read(T &res) { res = 0;char c = getchar();T f = 1; while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {putchar('-');x = -x;} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int N,M,MK,ci[205]; char x[MAXN],y[MAXN],ic[205],s[MAXN]; struct segAM { int head[62],next[MAXN],ch[MAXN][62],tot; segAM() { tot = 1;next[1] = 0; for(int i = 0 ; i <= 60; ++i) head[i] = 1; } void Insert(char c) { ++tot; next[tot] = head[ci[c]]; for(int i = 0 ; i <= 51 ; ++i) { for(int j = head[i] ; j && !ch[j][ci[c]] ; j = next[j]) { ch[j][ci[c]] = tot; } } head[ci[c]] = tot; } }S1,S2; const int BASE = 100000000; const int LEN = 8; struct Bignum { vector<int> v; Bignum operator = (int64 x) { v.clear(); do { v.pb(x % BASE); x /= BASE; }while(x); return *this; } friend Bignum operator + (const Bignum &a,const Bignum &b) { Bignum c;c.v.clear(); int p = 0,g = 0; while(1) { int x = g; if(p < a.v.size()) x += a.v[p]; if(p < b.v.size()) x += b.v[p]; ++p; if(!x) break; c.v.pb(x % BASE); g = x / BASE; } return c; } void print() { int s = v.size() - 1; printf("%d",v[s]); --s; for(int i = s ; i >= 0 ; --i) { printf("%08d",v[i]); } } }dp[MAXN][MAXN]; bool vis[MAXN][MAXN]; void get(int a,int b) { if(a == 0 || b == 0) return; if(vis[a][b]) return; dp[a][b] = 1; vis[a][b] = 1; for(int i = 0 ; i <= 51 ; ++i) { int ta = S1.ch[a][i],tb = S2.ch[b][i]; get(ta,tb); dp[a][b] = dp[a][b] + dp[ta][tb]; } } void get2(int a,int b,int dep) { if(a == 0 || b == 0) return; s[dep] = 0;if(dep != 0) printf("%s\n",s); for(int i = 0 ; i <= 51 ; ++i) { s[dep] = ic[i]; get2(S1.ch[a][i],S2.ch[b][i],dep + 1); } } void Solve() { read(N);read(M); scanf("%s%s",x + 1,y + 1); read(MK); for(char i = 'A' ; i <= 'Z' ; ++i) ci[i] = i - 'A',ic[i - 'A'] = i; for(char i = 'a' ; i <= 'z' ; ++i) ci[i] = i - 'a' + 26,ic[i - 'a' + 26] = i; for(int i = 1 ; i <= N ; ++i) S1.Insert(x[i]); for(int i = 1 ; i <= M ; ++i) S2.Insert(y[i]); if(MK == 1) get2(1,1,0); get(1,1); dp[1][1].print();enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
今天寫的題解全是FJOI啊(其實還寫了2道JOI的水題,太水了不寫題解了) zxg說讓咱們看看數學相關的集訓隊論文,而後作作FJ和SC的省選= = FJ貓錕 SC YJQ 咱們都表示絕不理解該省省選題和該省出題人有什麼關係,真的不懂中老年人思惟啊 可是反正都是要<del>無腦</del>提升刷題量嘛(大霧) 量變能帶來質變 ……嗎?code
39天NOI2018打卡ci