NOI2018 你的名字 題解

2021-09-27 09:08:03 字數 1949 閱讀 3205

題目鏈結

先考慮68分的做法:

求在a串**現,且在b串中沒出現的串的數量。

使用容斥,用a的不同子串數減去a,b的不同公共子串數。

先用雙指標,求出a的每個位置開始,在b中最多能向後匹配多遠。

然後,問題變為,給你一些區間,問它們的子區間中有多少不同的串。

因為每個串,都是原區間\([l,r]\)中\([l,i]\)的字尾。\((l<=i<=r)\)

而字尾就是在前面去掉一些字元,就是不斷走fa。

所以可以建出fa邊的樹,然後定位出這些位置,求這些點到根的路徑的並。

使用樹鏈合併即可,要注意壓縮的問題。

100分做法:與68基本相同,就是判斷子串\([a,b]\)是否出現多了乙個限制(\(l<=a,b<=r\))。

而乙個串匹配的位置,就是這個點子樹中紅點的集合。

紅點對應字首,所以這個限制可以轉化為字首位置的限制。

需要判斷乙個點的子樹中是否有x~y的數。使用dfs序+主席樹即可。

#include #include #define ll long long 

int fr[2000010],ne[2000010];

int v[2000010],bs = 0;

int wl[2000010],wr[2000010],tm = 1;

int xl[2000010];

struct sam

void clean()

np = sl = 1;

}void insert(char c, int wz)

if (p == 0) fa[np] = 1;

else }}

red[np] = wz;

}};void addb(int a, int b)

sam s,t;

void dfs1(int u)

int up[1000010];

char zf[1000010];

struct spx

spx(int u, int cd)

};spx px[1000010];

ll baoli(int s)

}ll rtn = 0;

for (int i = 2; i <= t.sl; i++) rtn += up[i];

return rtn;

}int he[24000010],cl[24000010],cr[24000010],sl = 0;

int jianshu(int l, int r)

int xiugai(int i, int l, int r, int j, int x)

cl[rt] = cl[i];

cr[rt] = cr[i];

int m = (l + r) >> 1;

if (j < m) cl[rt] = xiugai(cl[rt], l, m, j, x);

else cr[rt] = xiugai(cr[rt], m, r, j, x);

he[rt] = he[cl[rt]] + he[cr[rt]];

return rt;

}int chaxun(int i, int l, int r, int l, int r)

int gen[1000010],n;

bool zichuan(int i, int l, int r, int cd)

int main()

int m;

scanf("%d", &m);

for (int i = 0; i < m; i++)

}ll zo = 0;

for (int j = 1; j <= t.sl; j++) zo = zo + t.len[j] - t.len[t.fa[j]];

printf("%lld\n", zo - baoli(s));

}return 0;

}

NOI2018 你的名字

題目描述 小 a 被選為了 ion2018 的出題人,他精心準備了一道質量十分高的題目,且已經把除了題目命名以外的工作都做好了。由於 ion 已經舉辦了很多屆,所以在題目命名上也是有規定的,ion 命題手冊規定 每年由命題委員會規定乙個小寫字母字串,我們稱之為那一年的命名串,要求每道 題的名字必須是...

NOI2018 你的名字

sam寫的太不熟練了 sam上的線段樹合併也不熟練 調了半天樣例 給定乙個s,q次詢問,每次給出t,l,r,求對於s l,r 屬於t的子串卻不屬於s l,r 的子串有多少個 看上去挺簡潔的乙個問題。對於s 1,n 68pts?如果做過 heoi2015 最短不公共子串 就好做多了!可以對a,b分別建...

NOI2018 你的名字

嘟嘟嘟 這題以前寫過棄掉了,後來竟然連自己的68分寫法都看不懂了 這次回首這道題,心想怎麼說也得把這題切了,哪怕抄題解也行。但沒想到別人的題解自己怎麼也看不懂,最終還是自己搞出來了 我真nb 總用時前一天下午到第二天凌晨0 30 第二天半個上午。我們先來回顧 l 1,r n 的情況。大體思路就是求出...