日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C. Code a Trie(Trie+dfs+贪心)

發(fā)布時間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C. Code a Trie(Trie+dfs+贪心) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

C. Code a Trie

大佬題解,代碼基本就是抄的

對于每一個值計算所有串的LCA,也就是最長公共前綴,將該節(jié)點(Trie樹的節(jié)點)標記,對于這些字符串在LCA下面的點一定不存在(如果存在他們不會返回相同的值)

每個Trie樹中的節(jié)點只能被標記一次,并且從跟到LCA路徑上的變必須存在

dfs貪心計算每個子樹中最少的節(jié)點
插入時統(tǒng)計cnt[u]表示它的子樹中被標記為LCA的點的數(shù)量

  • 如果cnt[u]>1,這個點必選,如果說該節(jié)點沒被標記為LCA,那么它可以替代它一個兒子稱為那個值的LCA,如果被標記為LCA,它的兒子被標記那就必須選。
  • 如果cnt[u]=1,貪心選擇該點,兒子不選
  • 如果cnt[u]=0,貪心不選
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<stack> #include<queue> #include<bitset> #include<random> #include<bitset> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> #include<unordered_set> using namespace std; typedef long long ll; typedef pair<ll,int> pli; typedef pair<int,int> pii; const int N=500010; int n,a[N],b[N],cnt[N],ans; string s[N]; vector<string> g[N]; int tree[N][30],idx; bool lca[N]; void init() {cin>>n;int m=0;for(int i=1;i<=n;i++){cin>>s[i]>>a[i];m+=s[i].size();g[i].clear();}idx=0;for(int i=0;i<=m;i++)memset(tree[i],0,sizeof tree[i]);for(int i=0;i<=m;i++) lca[i]=0,cnt[i]=0; } bool cmp(string x,string y) {return x.size()<y.size(); } bool check(vector<string> &v) {//暴力尋找LCAsort(v.begin(),v.end(),cmp);int len=0;for(int i=0;i<v[0].size();i++){bool ok=1;for(int j=0;j<v.size()&&ok;j++)if(v[j][i]!=v[0][i]) ok=0;if(ok) len++;else break;}// Trie樹插入int p=0;for(int i=0;i<len;i++){cnt[p]++;//子樹中的lcaint c=v[0][i]-'a';if(tree[p][c]==-1) return 0; //節(jié)點不存在if(!tree[p][c]) tree[p][c]=++idx;p=tree[p][c];}if(lca[p]) return 0;lca[p]=1;cnt[p]++;// 標記一定不存在的點for(int i=0;i<v.size();i++){if(v[i].size()<=len) continue; int c=v[i][len]-'a';if(tree[p][c]>0) return 0;// 不存在的點存在了tree[p][c]=-1;}return 1; } void dfs(int u) {if(cnt[u]>1) ans++;bool fl=lca[u]==0;for(int i=0;i<26;i++){int son=tree[u][i];if(!son||son==-1) continue;if(cnt[son]==1){if(!fl) ans++;else fl=0;}else dfs(son);} } void work(int ca) {int m=0;for(int i=1;i<=n;i++)b[++m]=a[i];// 離散化sort(b+1,b+1+m);m=unique(b+1,b+1+m)-b-1;for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+m,a[i])-b;// 統(tǒng)計相同值的字符串for(int i=1;i<=n;i++)g[a[i]].push_back(s[i]);// 判斷進行插入for(int i=1;i<=m;i++)if(!check(g[i])){printf("Case #%d: -1\n",ca);return;}ans=0;cnt[0]++;dfs(0);printf("Case #%d: %d\n",ca,ans); } int main() {IO;int T=1;cin>>T;for(int ca=1;ca<=T;ca++){init();work(ca);}return 0; }

總結

以上是生活随笔為你收集整理的C. Code a Trie(Trie+dfs+贪心)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。