NOI2014 動物園題解

2022-02-08 23:05:31 字數 1577 閱讀 7280

2種解法, sb o(nlogn) 和 sb o(n) 。聽到過另一種牛逼 o(n), 感覺有點假就沒寫。

sb o(n log n), 首先都知道 nxt 的指向關係可以構成一顆內向樹, 隨便二分一下就行了。

//sb o(n log n)

#includeusing namespace std;

const int n = 1000003, mo = 1e9+7;

int n;

char s[n];

int ecnt, hd[n];

struct edge e[n];

void ad(int x,int y) ;

hd[x] = ecnt;

}int nxt[n];

long long ans;

int sta[n];

void dfs(int x,int fa,int d)

ans = ans*(l+1ll) % mo;

}if(x) sta[++*sta] = x;

for(int i=hd[x],y=e[i].v; i; i=e[i].nt,y=e[i].v)

if(y!=fa) dfs(y,x,d+1);

--*sta;

}int main()

// input

ecnt = 0;

for(int i=0;i<=n;++i) hd[i]=0;

for(int i=1;i<=n;++i) ad(nxt[i],i);

*sta = 0;

ans = 1ll;

dfs(0,0,0);

cout << ans << '\n';

}return 0;

}

雖然比較 sb , 但這個做法這個是 o(n) 的, 思路**於暴跳 nxt, 發現 i-1 的超過 \(\lfloor\dfrac\rfloor\) 的 border 不可能通過加乙個字元成為 i 的不超過 \(\lfloor\dfrac\rfloor\) 的 border, 所以再開個 nxt2 陣列記錄最長的不超過 \(\lfloor\dfrac\rfloor\) 的 border, 隨便搞搞就行了, 複雜度和經典 kmp 的複雜度一樣分析, 是均攤 o(n) 的。

// sb o(n)

#includeusing namespace std;

#define li long long

const int maxn = 1e6+5;

const int mod = 1000000007;

int len, nxx[maxn], nxt[maxn];

char s[maxn];

int dep[maxn];

int main()

dep[0] = 1;

for(int i=1;i<=len;++i) dep[i]=dep[nxt[i]]+1;

li ans = 1ll;

for(int i=1;i<=len;++i) ans = 1ll*ans*dep[nxx[i]]%mod;

cout<} return 0;

}

題解 NOI2014 動物園

luogu 輸入n組資料,每組資料報含乙個字串s,對於每個s,求出它的num陣列。num陣列的定義是 字串s的前i個字元構成的子串,既是它的字尾同時又是它的字首,並且該字尾與該字首不重疊,將這種字串的數量記作num i 為了避免大量的輸出,你不需要輸出num i 分別是多少,你只需要輸出所有 num...

題解 P2375 NOI2014 動物園

luogu 先用裸的 kmp 求出 fail next 陣列 隨便叫的無所謂啦 和不管重疊時的數量記為 ans ans 的定義類似於 fail next 然後再跑一遍,求出 frac 的數量,可結合 理解 includeusing namespace std int n,l,fail 1000010...

洛谷 P2375 NOI2014 動物園

其實對於乙個sum i 其值就等於sum next i sum next next i 1,然後我們可以記憶化,然後題目裡又有乙個限制,就是前字尾不能重合,那我們就找到最大但是不重合的那種情況,然後往小了列舉就好了.最後答案說要取模,所以不要忘了 ljx xhy yyq 排名無先後 1 includ...