题解:CF467D Fedor and Essay
CF467D Fedor and Essay
题目传送门
思路
将每一个字符串哈希,然后每个不同的哈希值对应一个点。每个对应点都开一个 pair,第一维是该串中 R 的个数,第二维是该串的长度。若串
将对应点建出来的图缩点,其中每个强连通分量的权值就是里面所有点以第一维优先的最小值。对缩点后的图拓扑排序,每个点的 pair 的值是它能够到达的所有点的最小值。最后答案将
Code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define pb push_back
#define pii pair<int,int>
#define mk make_pair
using namespace std;
const int N=1e6+10;
int n,m,color[N],p[N],cnt,tot,len,color_cnt,in[N],dfn[N],low[N];
pii a[N],a2[N];
vector<int>e[N],e2[N];
unordered_map<ull,int>mp;
string s[N];
inline pii change(string &s){
int cnt=0;
for(int i=0;i<(int)s.size();++i){
if(s[i]>='a'&&s[i]<='z')s[i]-='a'-'A';
if(s[i]=='R')++cnt;
}
return mk(cnt,s.size());
}
inline ull hashs(string s){
ull res=0,p=10007;
for(char c:s)res=res*p+c;
return res;
}
inline void dfs(int u){
dfn[u]=low[u]=++cnt;
in[u]=1;
p[++len]=u;
for(auto v:e[u]){
if(!dfn[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(in[v])low[u]=min(low[u],low[v]);
}
if(dfn[u]==low[u]){
++color_cnt;
a2[color_cnt]=a[u];
while(p[len]!=u){
in[p[len]]=0;
color[p[len]]=color_cnt;
if(a[p[len]].first<a2[color_cnt].first||(a[p[len]].first==a2[color_cnt].first&&a[p[len]].second<a2[color_cnt].second))
a2[color_cnt]=a[p[len]];
--len;
}
in[p[len]]=0;
color[p[len]]=color_cnt;
if(a[p[len]].first<a2[color_cnt].first||(a[p[len]].first==a2[color_cnt].first&&a[p[len]].second<a2[color_cnt].second))
a2[color_cnt]=a[p[len]];
--len;
}
}
inline void topusort(){
queue<int>q;
for(int i=1;i<=color_cnt;++i)if(!in[i])q.push(i);
while(q.size()){
int u=q.front();
q.pop();
for(auto v:e2[u]){
--in[v];
if(!in[v])q.push(v);
if(a2[u].first<a2[v].first||(a2[u].first==a2[v].first&&a2[u].second<a2[v].second))a2[v]=a2[u];
}
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;++i){
cin>>s[i];
pii id=change(s[i]);
ull ha=hashs(s[i]);
if(mp.find(ha)==mp.end()){
mp[ha]=++tot;
a[tot]=id;
}
}
string s1,s2;
cin>>m;
for(int i=1;i<=m;++i){
cin>>s1>>s2;
pii id=change(s1);
ull ha=hashs(s1);
if(mp.find(ha)==mp.end()){
mp[ha]=++tot;
a[tot]=id;
}
id=change(s2);
ull ha2=hashs(s2);
if(mp.find(ha2)==mp.end()){
mp[ha2]=++tot;
a[tot]=id;
}
e[mp[ha]].pb(mp[ha2]);
}
for(int i=1;i<=tot;++i)if(!dfn[i])dfs(i);
for(int i=1;i<=tot;++i){
for(auto v:e[i]){
if(color[i]!=color[v]){
e2[color[v]].pb(color[i]);
++in[color[i]];
}
}
}
topusort();
pii ans=mk(0,0);
for(int i=1;i<=n;++i){
ull ha=hashs(s[i]);
ans.first+=a2[color[mp[ha]]].first;
ans.second+=a2[color[mp[ha]]].second;
}
cout<<ans.first<<" "<<ans.second<<"\n";
return 0;
}