标签:hid -- struct namespace using http while problem opened
题目链接:Russian Code Cup 2017 - Finals B. Similar Words
题意:
给你n个字符串,现在让你构造一个集合X。
1.使得X的每个元素都是这n个字符串中的前缀。
2.X中任意两个元素都不相似(即一个字符串去掉第一个字符后不是另一个字符串)
题解:
我们将所有的前缀取出来,考虑将相似的连边。这里可以发现一个字符串去掉首字符后只有唯一的一个字符串。
所有将相似的连边后,就形成了一个森林。(判相似可以用hash,可以用AC自动机)
然后建完边后就是一个树形dp了。
这里hash容易被卡,双hash1.5s飘过。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=(a);i<=(b);++i) 3 #define mst(a,b) memset(a,b,sizeof(a)) 4 using namespace std; 5 typedef long long uu; 6 typedef pair<pair<uu,uu>,int>P; 7 namespace str_hash 8 { 9 const uu sd=1e9+7,D=1e9+9,N=1e6+7; 10 uu b[N],B[N]; 11 void init(){ 12 b[0]=1;F(i,1,N-1)b[i]=(b[i-1]*31)%sd; 13 B[0]=1;F(i,1,N-1)B[i]=(B[i-1]*31)&((1<<30)-1); 14 } 15 struct STR{ 16 int l; 17 uu *h,*h2; 18 void ins(char *s){ 19 int len=strlen(s+1); 20 h=new uu[len+1]; 21 h2=new uu[len+1]; 22 for(h[0]=0,h2[0]=0,l=1;s[l];l++) 23 { 24 h[l]=(h[l-1]*31+s[l])%sd; 25 h2[l]=(h2[l-1]*31+s[l])&((1<<30)-1); 26 } 27 l--; 28 } 29 pair<uu,uu> ask(int l,int r){ 30 return pair<uu,uu>((h[r]-h[l-1]*b[r-l+1]%sd+sd)%sd,(h2[r]-(h2[l-1]*B[r-l+1]&((1<<30)-1))+((1<<30)-1))&((1<<30)-1)); 31 } 32 }str[N]; 33 } 34 35 using namespace str_hash; 36 int t,n; 37 char s[N]; 38 vector<int>g[N]; 39 set<P>st; 40 int dp[N][2],in[N],vis[N]; 41 42 void dfs(int x) 43 { 44 dp[x][0]=1,dp[x][1]=0; 45 for(auto &it:g[x]) 46 { 47 dfs(it); 48 dp[x][0]+=dp[it][1]; 49 dp[x][1]+=max(dp[it][0],dp[it][1]); 50 } 51 } 52 53 54 int main(){ 55 init(),scanf("%d",&t); 56 while(t--) 57 { 58 scanf("%d",&n); 59 F(i,1,n) 60 { 61 scanf("%s",s+1); 62 str[i].ins(s); 63 } 64 int idx=0; 65 F(i,1,n)F(j,1,str[i].l) 66 { 67 ++idx; 68 pair<uu,uu> now=str[i].ask(1,j); 69 auto it=st.lower_bound(P(now,0)); 70 if(it!=st.end()&&it->first==now)vis[idx]=1; 71 else st.insert(P(now,idx)); 72 } 73 idx=0; 74 F(i,1,n)F(j,1,str[i].l) 75 { 76 ++idx; 77 if(j==1||vis[idx])continue; 78 pair<uu,uu> now=str[i].ask(2,j); 79 auto it=st.lower_bound(P(now,0)); 80 if(it!=st.end()&&it->first==now) 81 { 82 g[it->second].push_back(idx); 83 in[idx]++; 84 } 85 } 86 int ans=0; 87 F(i,1,idx)if(in[i]==0&&vis[i]==0) 88 { 89 dfs(i),ans+=max(dp[i][0],dp[i][1]); 90 } 91 printf("%d\n",ans); 92 st.clear(); 93 F(i,1,idx)dp[i][0]=dp[i][1]=0,g[i].clear(),vis[i]=in[i]=0; 94 } 95 return 0; 96 }
Russian Code Cup 2017 - Finals B. Similar Words(hash+树形dp)
标签:hid -- struct namespace using http while problem opened
原文地址:http://www.cnblogs.com/bin-gege/p/7647384.html