弱省互測 0 t2

2022-05-11 21:20:51 字數 1720 閱讀 2621

給定兩個字串 a 和 b,求下面四個問題的答案:

1.在 a 的子串中,不是 b 的子串的字串的數量。

2.在 a 的子串中,不是 b 的子串行的字串的數量。

3.在 a 的子串行中,不是 b 的子串的字串的數量。

4.在 a 的子串行中,不是 b 的子串行的字串的數量。

其中子串是指本質不同的子串,不同的位置相同的串也只算乙個串

|s|<=2000

構造倆自動機然後同時跑

構造乙個子串行自動機,再構造乙個字尾自動機,然後從根依次轉移,記錄狀態上的資訊,記憶化一下。

#include using namespace std;

const int mo=1e9+7, lim=100005;

int nid;

struct node

}po[lim], *it=po, *root[2], *last[2], *rt[2];

node *newnode()

void init()

void add1(int who, int ch)

if(!now)

node *y=now->c[ch];

if(y->len==now->len+1)

node *z=newnode();

*z=*y;

z->id=nid++;

z->len=now->len+1;

x->f=y->f=z;

for(; now && now->c[ch]==y; now=now->f)

}void cal(node *x)

x->flag=1;

x->s=1;

for(int ch=0; ch<26; ++ch)

} }}void build1(int who, char *s)

cal(root[who]);

}void build2(int who, char *s)

tc[*s-'a']=now;

} for(int ch=0; ch<26; ++ch)

cal(rt[who]);

}int vis[5005][5005];

int getans(node *x, node *y)

if(!y)

if(vis[x->id][y->id]!=-1)

int ret=0;

for(int ch=0; ch<26; ++ch)

} return vis[x->id][y->id]=ret;

}char s[2][2005], *it[2];

int main()

build2(0, it[0]);

build2(1, it[1]);

memset(vis, -1, sizeof vis); printf("%d\n", getans(root[0], root[1]));

memset(vis, -1, sizeof vis); printf("%d\n", getans(root[0], rt[1]));

memset(vis, -1, sizeof vis); printf("%d\n", getans(rt[0], root[1]));

memset(vis, -1, sizeof vis); printf("%d\n", getans(rt[0], rt[1]));

return 0;

}

弱省互測 0 t1

給乙個 n times m 的01網格,1不能走,從起點 1,1 走到 n,m 每次只能向下或向右走一格,問兩條不相交的路徑的方案數。n,m 1000 先考慮一條,再考慮去掉相交的情況。令 d a,b,c,d 表示從 a,b 走到 c,d 一條路徑的方案數,則可以簡單得到答案 ans d 2,1,n...

弱省互測 0 t3

要求給出下面 的答案然後構造輸入。給乙個圖,n 個點 m 條邊 q 次詢問,輸出所有點對之間最大權值最小的路徑。把每乙個詢問的輸出看成一條邊,建一棵最小生成樹。給輸出,要求構造輸入使得用所給 執行後得到的輸出和給出的輸出相同。所給 n 次 dijkstra 求兩點間最短路 考慮一下貪心。首先還是把每...

弱省互測 2 t2

給兩個樹,大小分別為n和m,現在兩棵樹各選一些點 包括1 使得這棵樹以1號點為根同構 同構就是每個點的孩子數目相同 求最大的同構樹。n,m 500 我們從兩棵樹中各取出乙個點,考慮以這兩個點為根能得到的最大同構數。容易得到 設 d i,j 表示第一棵樹選 i 號點,第二棵樹選 j 號點所能得到的最大...