牛客 - Elo mountains(AC自动机+可持久化数组优化)
生活随笔
收集整理的這篇文章主要介紹了
牛客 - Elo mountains(AC自动机+可持久化数组优化)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目鏈接:點(diǎn)擊查看
題目分析:初始時(shí)給出一棵以點(diǎn) 000 為根節(jié)點(diǎn)的字典樹,設(shè) arriarr_iarri? 為從根節(jié)點(diǎn)出發(fā)到達(dá)點(diǎn) iii 的字符串,需要回答對(duì)于每個(gè) i∈[1,n]i\in[1,n]i∈[1,n] 時(shí)的 ∑k=1nf(arri,arrk)\sum_{k=1}^{n}f(arr_i,arr_k)∑k=1n?f(arri?,arrk?),其中 f(s,t)f(s,t)f(s,t) 代表的是字符串 sss 在字符串 ttt 中出現(xiàn)的次數(shù)
題目分析:
先附上官方題解:
本題難點(diǎn)及解決方法:
需要注意的一個(gè)小坑點(diǎn)就是,因?yàn)樽值錁渖系淖址傞L(zhǎng)最大可能是 O(n2)O(n^2)O(n2) 級(jí)別的,所以答案可能會(huì)爆 intintint,記得開 longlonglong\ longlong?long
時(shí)間復(fù)雜度:O(nlogn)O(nlogn)O(nlogn)
代碼:
// Problem: Elo mountains // Contest: NowCoder // URL: https://ac.nowcoder.com/acm/contest/17148/G // Memory Limit: 1048576 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<list> #include<unordered_map> #define lowbit(x) x&-x using namespace std; typedef long long LL; typedef unsigned long long ull; template<typename T> inline void read(T &x) {T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f; } template<typename T> inline void write(T x) {if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0'); } const int inf=0x3f3f3f3f; const int N=1e5+100; const int M=1e5; vector<pair<int,int>>edge[N];//原樹 vector<int>node[N];//fail樹 unordered_map<int,int>trans[N];//原樹的字典樹 struct Node {int l,r,val; }tree[N*20];//可持久化數(shù)組 int trie[N],fail[N],tot; LL dp[N],sz[N]; int newnode() {tot++;tree[tot].l=tree[tot].r=tree[tot].val=0;return tot; } void add(int &k,int pos,int val,int l,int r) {int nk=newnode();tree[nk]=tree[k];k=nk;if(l==r) {tree[k].val+=val;return;}int mid=(l+r)>>1;if(pos<=mid) {add(tree[k].l,pos,val,l,mid);} else {add(tree[k].r,pos,val,mid+1,r);} } int ask(int k,int pos,int l,int r) {if(l==r) {return tree[k].val;}int mid=(l+r)>>1;if(pos<=mid) {return ask(tree[k].l,pos,l,mid);} else {return ask(tree[k].r,pos,mid+1,r);} } void getfail() {queue<int>q;for(auto it:trans[0]) {int u=0,v=it.second,to=it.first;add(trie[u],to,v,1,M);fail[v]=u;q.push(v);}while(q.size()) {int u=q.front();q.pop();trie[u]=trie[fail[u]];for(auto it:trans[u]) {int v=it.second,to=it.first;int delta=v-ask(trie[u],to,1,M);add(trie[u],to,delta,1,M);fail[v]=ask(trie[fail[u]],to,1,M);q.push(v);}} } void buildfail(int n) {for(int i=1;i<=n;i++) {dp[fail[i]]+=sz[i];node[fail[i]].push_back(i);} } void dfs1(int u,int fa) {sz[u]=1;for(auto it:edge[u]) {int v=it.first,to=it.second;if(v==fa) {continue;}trans[u][to]=v;dfs1(v,u);sz[u]+=sz[v];} } void dfs2(int u) {for(auto v:node[u]) {dfs2(v);dp[u]+=dp[v];} } void init() {tot=-1;newnode(); } int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);init();int n;read(n);for(int i=1;i<=n;i++) {int u,v,w;read(u),read(v),read(w);edge[u].push_back({v,w});edge[v].push_back({u,w});}dfs1(0,-1);//建字典樹getfail();//得到fail邊buildfail(n);//建fail樹dfs2(0);//fail樹上dpfor(int i=1;i<=n;i++) {printf("%lld\n",dp[i]+sz[i]);}return 0; }總結(jié)
以上是生活随笔為你收集整理的牛客 - Elo mountains(AC自动机+可持久化数组优化)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AC自动机解决字符集很大的情况(可持久化
- 下一篇: CodeForces - 1523E C